【问题标题】:ListView won't update in fragmentListView 不会在片段中更新
【发布时间】:2014-05-11 17:13:03
【问题描述】:

我正在为我的学校构建一个应用程序。我使用 Android Studio 的默认 Navigation Drawer Fragment 和 Main Activity,并根据用户在抽屉中选择的内容填充 Fragment。

问题是我的一个片段从互联网上获取数据,并用它设置了一个列表视图。但是列表视图没有更新,并且片段保持空白。我认为这是更新 UI 的问题,我做得不对。

有片段代码:

public class NewsFragment extends Fragment {

// ASYNC TASK VARIABLES
NewsAsyncTask crackerTask = new NewsAsyncTask();
String NEWSURL = "http://---.--/H--e.aspx";
String ALERTSURL = "http://---.--/H--e.aspx";
String EVENTSURL = "http://---.--/H--e.aspx";
String string1 = "";
String FINALSTRING = "";

public List<NewsItem> myNews = new ArrayList<NewsItem>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //Inflate the layout for this fragment
    return inflater.inflate(R.layout.news_fragment, container, false);

}


@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // INSTANTIATING AND INFLATING THE TABBED LAYOUT
    super.onCreate(savedInstanceState);

    View container = (View) getActivity().findViewById(R.id.news_layout_container) ;

    // ASYNC TASK METHOD EXECUTION UNDER IF STATEMENT
    if (this.isNetworkAvailable()) {

        crackerTask.execute(NEWSURL);
        populateListView();
        registerClickOnListItem();
        // getView().invalidate();

    }
    else{

        Toast.makeText(getActivity(), "No internet connection.",
                Toast.LENGTH_SHORT).show();
    }
}

// CUSTOM METHODS ////////////////////////////////////////////////////
private void actionButtonRefreshPressed() {
    if (this.isNetworkAvailable()) {
        new NewsAsyncTask().execute(NEWSURL); // calling NEW asynctask
        populateListView();
        registerClickOnListItem();

        // because an asynctask
        // can be executed only
        // once.
    }
}

private void populateNewsList(String title, String summary, String date,
                              String link) {
    myNews.add(new NewsItem(title, summary, date, link));

}

private void populateListView() {
    ArrayAdapter<NewsItem> adapter = new MyListAdapter();
    ListView newslist = (ListView) getView().findViewById(R.id.newsListView);
    newslist.setAdapter(adapter);
}

private void registerClickOnListItem() {
    ListView list = (ListView) getView().findViewById(R.id.newsListView);
    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View viewClicked,
                                int position, long id) {
            // shows toast with info
            NewsItem clickedNewsItem = myNews.get(position);
            String message = "You clicked position " + position
                    + " Which is " + clickedNewsItem.title;
            Toast.makeText(getActivity(), message,
                    Toast.LENGTH_SHORT).show(); // .show is important!
            // otherwise it won't show.
        }
    });
}

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager
            .getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

// CUSTOM MINI CLASSES /////////////////////////////////////////////////
private class NewsAsyncTask extends AsyncTask<String, String, String> {
    // Genetics of an AsyncTask:
    // 1. Type of reference(s) passed to doInBackground()
    // 2. Type of reference passed to onProgressUpdate()
    // 3. Type of reference returned by doInBackground(). Value passed to
    // onPostExecute()
    ProgressDialog dialog1;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dialog1 = ProgressDialog.show(getActivity(), "Loading",
                "Fetching data from web...");
    }

    @Override
    protected String doInBackground(String... arguments) {
        // extract arguments
        String newsurl = arguments[0];
        //
        Document root = null;

        try {
            root = Jsoup.connect(newsurl).get();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
        if (root != null) {

            Elements myElements = root.getElementsByClass("news_list")
                    .first().getElementsByTag("table");

            for (Element el : myElements) {
                Element title = el.getElementsByClass("home_title").first();
                Element date = el.getElementsByClass("home_date").first();
                Element link = el.getElementsByClass("news_list_image")
                        .first();
                Element summary = el.getElementsByClass("summary").first();

                populateNewsList(title.text(), summary.text(), date.text(),
                        link.child(0).attr("href"));

            }

            Log.i("ELEMENTS HTML", string1);

        } else {
            string1 = "FAILED TO LOAD";
        }
        return string1;

    }

    @Override
    protected void onPostExecute(String string1) {
        // super.onPostExecute(result);
        if (string1.equals("FAILED TO LOAD")) {
          //  tv2.setText("Failed to load. Check your internet connection.");
            if (dialog1 != null) {
                if (dialog1.isShowing()) {
                    dialog1.dismiss();
                }
            }
            Toast.makeText(getActivity(),
                    "No web connectivity. Try again later.",
                    Toast.LENGTH_LONG).show();

        }else{
           //presumably the download worked so update adapter
          ListView newslist = (ListView) getView().findViewById(R.id.newsListView);
          ((ArrayAdapter)newsList.getAdapter()).notifyDataSetChanged();

        }
        FINALSTRING = string1;
       // tv2.setText(FINALSTRING);
        if (dialog1 != null) {
            if (dialog1.isShowing()) {
                dialog1.dismiss();
            }
        }
    }

}

private class MyListAdapter extends ArrayAdapter<NewsItem> {
    public MyListAdapter() {
        super(getActivity(), R.layout.news_item, myNews);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // make sure we have a view to work with in the lines below, may be
        // given null
        View newsItem = convertView;
        if (newsItem == null) {
            newsItem = getActivity().getLayoutInflater().inflate(R.layout.news_item,
                    parent, false);
        }

        // find the NewsItem we have to work with.
        NewsItem currentNews = myNews.get(position);
        // fill the view.
        ImageView imageView = (ImageView) newsItem
                .findViewById(R.id.newsitem_icon);
        imageView.setImageResource(R.drawable.test_icon); // THIS IS GOING
        // TO BE CHANGED
        // SO IT DOESN'T
        // USE THE
        // DRAWABLE
        // Summary
        TextView summaryText = (TextView) newsItem
                .findViewById(R.id.newsitem_summary);
        summaryText.setText(currentNews.getSummary());
        // Date
        TextView dateText = (TextView) newsItem
                .findViewById(R.id.newsitem_date);
        dateText.setText(currentNews.getDate());
        // Title
        TextView titleText = (TextView) newsItem
                .findViewById(R.id.newsitem_title);
        titleText.setText(currentNews.getTitle());
        return newsItem;
    }
}
}

我在调试代码时留下了一些东西,对不起(它最初是在一个活动中并且它工作,当我在片段中传输所有内容时出现问题)。

编辑:由于我尝试了这么多变体,我想错误是我试图显示的列表视图是空的。我尝试将Log.i("TAG", myNews.get(0).title); 放在invalidate(); 的位置,它返回一个索引越界异常。但是我找不到错误的根源。

【问题讨论】:

    标签: android android-fragments android-listview android-activity android-view


    【解决方案1】:

    您可能应该在您的适配器(而不是列表视图)上调用 notifyDataSetChanged。在执行后的 AsyncTask 中调用它。

    【讨论】:

    • 你能编辑出应该放置的代码部分吗,因为我不太明白,我正在努力做到这一点,比如 15 分钟。
    【解决方案2】:

    您正在使您的视图无效:getView().invalidate(); 是时候打电话给requestLayout()了。

    【讨论】:

    • 我对更新 UI 还是很陌生。你能详细说明在哪里以及如何?谢谢你:))
    • if (this.isNetworkAvailable()) { crackerTask.execute(NEWSURL);填充列表视图(); registerClickOnListItem(); getView().invalidate();这会使您的视图无效,因此您需要撤消验证或重绘视图
    • 应该是这样的:getView().notifyDataSetChanged();如果您的数据在异步任务中发生变化
    • 把getView().notifyDataSetChanged();给出错误并告诉我该方法无法解决。 getView().requestLayout() 也什么都不做。我想知道错误是否不在其他地方,我不知道;/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多