【问题标题】:Integrated News feed not displaying (ANDROID KITKAT)集成的新闻提要未显示(ANDROID KITKAT)
【发布时间】:2017-03-11 14:43:13
【问题描述】:

所以我正在为爱狗人士创建一个应用程序(大学项目),并且我正在尝试创建一个集成的新闻提要,以显示与狗相关的新闻,并在点击时将用户带到网站。我制作了一个虚拟应用程序来测试系统,它运行良好。一旦我将它切换到我当前的 Dog 应用程序,它就完全停止工作。问题是我用来显示文章列表的 Activity 完全没有显示任何内容。

这里有 2 个 Activity,一个 Links Activity 和一个 newsItem Activity。 Links Activity 是页面使用的主要活动,并在页面上以某种方式显示文本。 newsItem Activity 充当 getter,并通过 JSON 文件查找数组中的某些单词并将它们解析回应用程序。我还使用 localHost 来托管 JSON 文件。

如果你们能在这里帮助我,那就太棒了!我撞到了一堵完整的砖墙。

Links_Activity 类连接到 activity_links.xml 文件

newsItem 类连接到 Article.xml 文件

Links_Activity 类

   package uk.ac.napier.doggo;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;


import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.squareup.picasso.Picasso;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class Links_Activity extends AppCompatActivity {

    private List<newsItem> newsFeed = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_links);

        engine();
        addClickListener();

    }

    private void engine() {
        RequestQueue queue = Volley.newRequestQueue(this);

        JsonObjectRequest myReq = new JsonObjectRequest(Request.Method.GET,
                "http://10.0.2.2/news.json",
                null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            JSONArray newsItems = response.getJSONArray("newsItems");

                            for (int i = 0; i < newsItems.length(); i++) {
                                JSONObject temp = newsItems.getJSONObject(i);

                                String image = temp.getString("image");
                                String title = temp.getString("title");
                                String time = temp.getString("time");
                                String date = temp.getString("date");
                                String content = temp.getString("content");
                                String link = temp.getString("link");


                                newsFeed.add(new newsItem(title, content, date, time, link, image));

                            }
                        } catch(JSONException e){
                            Log.i("myTag", e.toString());
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.i("myTag", error.toString());
                    }
                });



        myReq.setRetryPolicy(new DefaultRetryPolicy(
                30*1000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(myReq);



        ArrayAdapter<newsItem> adapter = new customAdapter();

        ListView  newsItems = (ListView) (findViewById(R.id.newsItems));
        newsItems.setAdapter(adapter);

    }

    private void addClickListener() {
        ListView newsItems = (ListView) (findViewById(R.id.newsItems));
        newsItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                newsItem currentItem = newsFeed.get(position);
                Intent i = new Intent (Intent.ACTION_VIEW);
                i.setData(Uri.parse(currentItem.getUrl()));
                startActivity(i);
            }
        });
    }



        private class customAdapter extends ArrayAdapter<newsItem> {
                public customAdapter() {
            super(Links_Activity.this, R.layout.article, newsFeed);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            if(convertView == null) {
                convertView = getLayoutInflater().inflate(R.layout.article, parent, false);
            }

            newsItem currentItem = newsFeed.get(position);

            ImageView newsImage = (ImageView) convertView.findViewById(R.id.leftIco);
            TextView heading = (TextView) convertView.findViewById(R.id.heading);
            TextView desc = (TextView) convertView.findViewById(R.id.desc);

            heading.setText(currentItem.getNewsHeading());
            desc.setText(currentItem.getNewsDesc());

            Picasso.with(Links_Activity.this).load(currentItem.getImageURL()).into(newsImage);


            return convertView;
        }

    }

    public void Back(View view) {
        Intent startBackActivity = new Intent(this, Menu_Activity.class);
        startActivity(startBackActivity);
    }
}

activity_links.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="News Feed"
    android:textSize="25sp"
    android:textAlignment="center"
    android:id="@+id/logo"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"/>

<TextView
    android:text="Articles Courtesy of Dogster.com"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/textView"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true" />

<ListView
    android:layout_width="wrap_content"
    android:layout_height="400dp"
    android:id="@+id/newsItems"
    android:layout_centerVertical="true"
    android:layout_alignParentStart="true" />

</RelativeLayout>

newsItem 类

package uk.ac.napier.doggo;

import java.util.PriorityQueue;

/**
 * Created by MarkB on 10/03/2017.
 */

public class newsItem {

    private String newsHeading;
    private String newsDesc;
    private String newsDescSmall;
    private String time;
    private String date;
    private String url;
    private String imageURL;

    public newsItem(String newsHeading, String newsDesc, String date,  String time, String url, String imageURL) {
        this.newsHeading = newsHeading;
        this.newsDesc = newsDesc;
        this.time = time;
        this.date = date;
        this.url = url;
        this.imageURL = imageURL;

        this.newsDescSmall = this.newsDesc.substring(0, 50) + "...";
    }

    public String getNewsHeading() {
        return newsHeading;
    }

    public String getNewsDesc() {
        return newsDesc;
    }

    public String getTime() {
        return time;
    }

    public String getDate() {
        return date;
    }

    public String getUrl() {
        return url;
    }

    public String getImageURL() {
        return imageURL;
    }
}

article.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">

<ImageView
    android:layout_width="80dp"
    android:layout_height="100dp"
    android:id="@+id/leftIco"
    android:src="@mipmap/ic_launcher"
    android:maxHeight="100dp"
    android:maxWidth="100dp"
    android:adjustViewBounds="true"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="16sp"
    android:text="Heading Text"
    android:id="@+id/heading"
    android:scrollHorizontally="false"
    android:maxLines="100"
    android:ellipsize="none"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/leftIco"
    android:layout_toEndOf="@+id/leftIco"
    android:layout_marginLeft="24dp"
    android:layout_marginStart="24dp"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Description"
    android:id="@+id/desc"
    android:lineSpacingExtra="-3dp"
    android:layout_marginBottom="26dp"
    android:layout_alignBottom="@+id/leftIco"
    android:layout_alignLeft="@+id/heading"
    android:layout_alignStart="@+id/heading"/>




</RelativeLayout>

AndroidManifest.xml 供参考

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="uk.ac.napier.doggo">

    <uses-permission android:name="android.permission.INTERNET">
</uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".Home_Screen_Activity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".Details_Activity" />
        <activity android:name=".Menu_Activity" />
        <activity android:name=".Reminders_Activity" />
        <activity android:name=".Health_Tracker_Activity" />
        <activity android:name=".Routes_Activity" />
        <activity android:name=".Route_Complete_Activity" />
        <activity android:name=".History_Activity" />
        <activity android:name=".Links_Activity" >

        </activity>

        <activity android:name=".TimePopUp_Activity"
        android:theme="@style/AppTheme.CustomTheme" >
        </activity>

    </application>

</manifest>

最后是 news.JSON 文件

{"newsItems":[
{
"image": "http://www.dogster.com/wp-content/uploads/2017/03/16806949_152063731974308_6992949846293798966_n-Cropped.jpg",
"title": "Artist Arien Smith Imagines Disney Princesses With Service Dogs",
"time": "10:00am ",
"date": "22 Jun ",
"content": "So far, the artist has drawn Cinderella and Snow White with     service dogs, with the hope of raising awareness and money for his own helper.",
"link": "http://www.dogster.com/lifestyle/artist-arien-smith-imagines-disney-princesses-with-service-dogs"
},
{
"image": "http://www.dogster.com/wp-content/uploads/2016/06/Stalking-predatory-hero.png",
"title": "Is Your Dog a Bully?",
"time":"12:00am ",
"date":"Jun 12",
"content": "Dogs who bully not only start fights, but they can turn timid dogs into bullies themselves. Let's look at the signs of bullying and how to help your dog stop this behavior.",
"link": "http://www.dogster.com/lifestyle/is-your-dog-a-bully"
}
]
}

【问题讨论】:

  • 有什么有用的错误吗?
  • 这段代码还能编译吗? customAdapter 方法看起来很可疑。
  • 代码构建很好,很抱歉,但它没有显示任何相关的错误。我认为这可能与本地主机和 JSON 对象请求有关
  • 为什么不通过在 onResponse 中打印所述 JSON 来确保它与 JSON 有关?查明问题所在将是调试问题的良好第一步。
  • 我是否做一些类似于我对 catch 异常所做的事情来做到这一点?我仍然是 Android 的菜鸟

标签: java android json xml feed


【解决方案1】:

你从来没有打电话给adapter.notifyDataSetChanged()

        newsFeed.add(new newsItem(title, content, date, time, link, image));
    }  // end loop
    // notify the adapter to display the new data 
    adapter.notifyDataSetChanged()
} catch(JSONException e){
    Log.i("myTag", e.toString());
}

但是,你有一个 ArrayAdapter,所以只需添加它,而不是 Arraylist,那么你不需要通知

        // See here
        adapter.add(new newsItem(title, content, date, time, link, image));
    }  // end loop
} catch(JSONException e){
    Log.i("myTag", e.toString());
}

对您的代码进行一些重新安排,这应该可以工作。

public class LinksActivity extends AppCompatActivity 
  implements AdapterView.OnItemClickListener, Response.ErrorListener {

    private List<NewsItem> newsFeed = new ArrayList<>();
    private ArrayAdapter<NewsItem>  adapter;

    // Moved the Volley response to top-level
    private Response.Listener<JSONObject>  newsListener = new Response.Listener<JSONObject>()  {        

        @Override
        public void onResponse(JSONObject response) {
            try {
                JSONArray newsItems = response.getJSONArray("newsItems");

                for (int i = 0; i < newsItems.length(); i++) {
                    JSONObject temp = newsItems.getJSONObject(i);

                    String image = temp.getString("image");
                    String title = temp.getString("title");
                    String time = temp.getString("time");
                    String date = temp.getString("date");
                    String content = temp.getString("content");
                    String link = temp.getString("link");


                    newsFeed.add(new newsItem(title, content, date, time, link, image));
                }

                // Important!
                adapter.notifyDataSetChanged();

            } catch(JSONException e){
                Log.i("myTag", e.toString());
            }
        }
    };

    // This is Volley's error listener over the entire Activity
    @Override
    public void onErrorResponse(VolleyError error) {
        Log.i("myTag", error.toString());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_links);

        // Set and define the List and Adapter here
        ListView  newsItems = (ListView) findViewById(R.id.newsItems);
        newsItems.setOnItemClickListener(this);

        adapter = new CustomAdapter();
        newsItems.setAdapter(adapter);

        engine();
    }

    private void engine() {
        RequestQueue queue = Volley.newRequestQueue(this);

        // Now this method is much 'cleaner'
        JsonObjectRequest myReq = new JsonObjectRequest(Request.Method.GET,
                "http://10.0.2.2/news.json",
                null, 
                newsListener, this);

        myReq.setRetryPolicy(new DefaultRetryPolicy(
                30*1000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(myReq);
    }

    // The Activity itself handles the clicking
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        NewsItem currentItem = newsFeed.get(position);
        Intent i = new Intent (Intent.ACTION_VIEW);
        i.setData(Uri.parse(currentItem.getUrl()));
        startActivity(i);
    }
}

【讨论】:

  • 你能在 Links_Activity 上告诉我它会去哪里吗?
  • 我不完全明白我把它放在哪里以及如何处理这些信息。我对 android 开发很陌生
  • 这不是 Android 特定的。这只是java。您已经拥有 newsFeed.add 。替换它
  • 我知道这很令人沮丧,但你必须明白我是一个完全的菜鸟。你能告诉我代码和它适合它的地方吗?就像实际编写代码一样,因为我不了解术语或这些方法中的任何一个如何工作。
  • 基本上,你添加到列表成功了,是的。但是 Android 不会更新 ArrayAdapter,除非你明确告诉它。因此adapter.notifyDataSetChanged() 需要在for 循环之后在onResponse 中。您可以查看我对相关部分的回答
【解决方案2】:

试试这个:

将数组项传递给适配器:

customAdapter adapter = new customAdapter(this, newsFeed);
ListView  newsItems = (ListView) (findViewById(R.id.newsItems));
newsItems.setAdapter(adapter);

现在在适配器类中使用:

private List<newsItem> newsFeed_list ;

   public customAdapter(Context context, ArrayList<newsItem> items) {
        super(context, items);
        this.newsFeed_list = items;
    }

并使用以下方法获取对象:

newsItem currentItem = newsFeed_list.get(position);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    相关资源
    最近更新 更多