![](/img/trans.png)
[英]Android RecyclerView not refreshing on adapter.notifyDataSetChanged
[英]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.