簡體   English   中英

盡管我使用了Adapter.notifyDataSetChanged(),但在更改數據集后,Android ListView不會刷新

[英]Android ListView not refreshing after dataset changed, though I have used the Adapter.notifyDataSetChanged()

我知道這里曾問過類似的問題幾次,但是沒有一個問題可以幫助我解決我的問題,所以我只需要再問一次。

我所擁有的應用程序具有一個片段,該片段在主活動中擁有一個ListView,並且我使用了PullableListView,因此當我向上拖動ListView時,它將觸發onLoadMore()回調方法從服務器加載更多數據。 加載數據后,數據將保存到SQLiteDB,然后由ListView用來顯示更新的數據。

這是我的PullableListViewFragment.java:

public class PullableListViewFragment extends Fragment implements
    OnItemClickListener {

private ListView listView;
private PullToRefreshLayout ptrl;

private MissionDB mMissionDB;
private List<MissionEntity> mData;

private MissionListAdapter mAdapter;

/**
 * Specify the exact mission that will be displayed in MissionDetailActivity
 */
private int mIndexOfMission;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View pullableLayout = inflater.inflate(R.layout.pullable_layout, container, false);
    listView = (ListView) pullableLayout.findViewById(R.id.content_view);
    listView.setDivider(null);
    ptrl = (PullToRefreshLayout) pullableLayout.findViewById(R.id.refresh_view);
    ptrl.setOnRefreshListener(new RefreshListener());
    loadData();

    Log.d(Constants.LOG_TAG, "onCreateView Called from PullableListViewFragment");

    return pullableLayout;
}

/**
 * Initialise ListView
 */
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mAdapter = new MissionListAdapter(getActivity(), mData);
    listView.setAdapter(mAdapter);
    listView.setOnItemClickListener(this);
    mAdapter.notifyDataSetChanged();
    Log.d(Constants.LOG_TAG, "onActivityCreated Called from PullableListViewFragment");
}

/**
 * Load data from db
 */
private void loadData() {
    mData = new ArrayList<>();
    mMissionDB = MissionDB.getInstance(MyApplication.getContext());
    mData = mMissionDB.loadMission();
}

/**
 * OnItemClick event
 */
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {
    Intent intent = new Intent(getActivity(), MissionDetailActivity.class);
    mIndexOfMission = mData.get((int) id).getId();
    intent.putExtra("Position", mIndexOfMission);
    startActivity(intent);
}

}

這是RefreshListener.java:

public class RefreshListener implements PullToRefreshLayout.OnRefreshListener {

private MissionDB mMissionDB = MissionDB.getInstance(MyApplication.getContext());

@Override
public void onLoadMore(final PullToRefreshLayout pullToRefreshLayout) {
    // LoadMore
    new Handler() {

        @Override
        public void handleMessage(Message msg) {

            /** When drag up, load more mission that is older and not out of date */
            mMissionDB.open();
            int id = mMissionDB.getMaxOrMinId("MIN");
            final JSONObject oldMission = new JSONObject();
            try {
                oldMission.put("platform", "1");
                oldMission.put("more", 0);
                oldMission.put("id", id);
                oldMission.put("size", 1);
            } catch (JSONException e) {
                e.printStackTrace();
            }

            Thread t = new Thread(new Runnable() {

                @Override
                public void run() {
                    HttpRequest.sendHttpRequest(Constants.PULLORDRAG_TO_LOAD_MISSION_URL, oldMission, new HttpCallbackListener() {

                        @Override
                        public void onFinish(String response) {
                            MissionEntity mMission = new MissionEntity();

                            /** Save new mission to mission database */
                            try {
                                JSONObject jsonObject = new JSONObject(response);
                                JSONArray missionList = jsonObject.getJSONArray("taskList");
                                for (int i = 0; i < missionList.length(); i++) {
                                    JSONObject mission = missionList.getJSONObject(i);
                                    mMission.setId(mission.getInt("id"));
                                    mMission.setDownloadUrl(mission.getString("appPath"));
                                    mMission.setCreateTime(mission.getString("taskId"));
                                    mMission.setImageUrl(mission.getString("appImg"));
                                    mMission.setTitleName(mission.getString("appName"));
                                    mMission.setRemainTime("Remain: 1d 11h 23m 36s");
                                    mMission.setParticipant("135");
                                    mMission.setCreator("Google");
                                    mMission.setRequirement(mission.getString("description"));
                                    mMission.setRewards("TODO");
                                    mMission.setAttention("TODO");
                                    mMission.setValidDate(mission.getString("deadline"));
                                    mMission.setAccepted("0");
                                    mMission.setCollected("0");
                                    mMission.setAccomplished("0");
                                    mMissionDB.saveMission(mMission);
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onError(Exception e) {
                            e.printStackTrace();
                            Log.e(Constants.LOG_TAG, "Error while loading more");
                        }
                    });
                }
            });

            try {
                t.start();
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            pullToRefreshLayout.loadmoreFinish(PullToRefreshLayout.SUCCEED);

            //==================Update 1==================
            ListView list = (ListView) pullToRefreshLayout.findViewById(R.id.content_view);
            List<MissionEntity> missionList = mMissionDB.loadMission();
            Log.d(Constants.LOG_TAG, "mission size" + missionList.size());
            MissionListAdapter adapter = (MissionListAdapter) list.getAdapter();
            adapter.setData(missionList);
            adapter.notifyDataSetChanged();
            list.setAdapter(adapter);
            //==================Update 1==================
        }
    }.sendEmptyMessageDelayed(0, 1000);
}

}

PullToRefreshLayout是一個自定義的RelativeLayout,它定義了一個內部接口OnRefreshListener ,一旦調用onLoadMore()回調方法,該內部接口就會被調用。

我在該片段中使用ListView是實現了一個可拉接口,可以拖動一個PullableListView。

我的Pullable.java:

public interface Pullable
{
    /**
     * If pull up is not needed, set canPullUp to false
     * 
     * @return true if the View can pull up
     */
    boolean canPullUp();
}

這是片段的layout.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="#f2f2f2"
          android:orientation="vertical">

<View
    android:layout_width="match_parent"
    android:layout_height="5dp" />

<pulltorefresh.PullToRefreshLayout
    android:id="@+id/refresh_view"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include layout="@layout/refresh_head"/>

    <!-- Supports all view that implemented the Pullable interface -->
    <pulltorefresh.PullableListView
        android:id="@+id/content_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <include layout="@layout/load_more"/>

</pulltorefresh.PullToRefreshLayout>

</LinearLayout>

問題是當在onLoadMore()方法之后更改SQLiteDB中的數據時,片段中的ListView不會刷新自身,除非我導航到同一主要活動中的另一個片段,然后再返回。

我在這里能找到的所有方法都很累,但沒有一個可以幫助。

任何人都可以告訴我,當SQLiteDB中的數據更改時,如何使ListView刷新。

[更新1]我在onLoadMore()回調中添加了一些代碼,從服務器獲取一些數據后數據的大小保持不變,我認為這就是為什么ListVie不刷新的問題,有趣的是如果我將Thread.sleep(500) mMission.loadMission() Thread.sleep(500)之前,則數據大小正確且一切都很好。 知道為什么嗎?

在onLoadMore方法中,您僅加載數據並保存到數據庫中。 加載數據后,您應該更新適配器的數據源並調用adapter.notifyDataSetChanged()以刷新列表視圖。 或者,您可以通知片段從數據庫中重新加載數據。

確保先加載更多數據,然后獲取數據。 而且我認為您的mMissionDB確實發生了變化,但是mData呢? 您的適配器實際上是使用mData作為數據源,因此您應該更新mData,並調用adapter.notifyDataSetChanged()刷新列表視圖。 希望它能對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM