如何在片段中保存列表视图 items/adapter 并从返回堆栈中恢复
how to save listview items/adapter in fragment and restore from back stack
我曾尝试搜索此问题,但找不到任何解决方案。
我在片段中保存 ListView 项目时遇到问题。情况是我有几个片段
let say FRAGMENT A, FRAGMENT B and FRAGMENT C, and FRAGMENT A has a
listview, the item of the listview can be changed when user scroll
(just like timeline in social media apps). When I change the fragment
A, I used addToBackStack(null) method.
问题是,如果按下后退按钮,如何保存列表视图并恢复它?
onSaveInstanceState() is never called because the Activity host is never killed, only change the fragment using this:
public void changeFragment(Fragment fragment, ColorDrawable colorDrawable){
Fragment newFrag = fragment;
ColorDrawable newColor = colorDrawable;
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped){ //fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_fragment, fragment);
ft.addToBackStack(backStateName);
ft.commit();
}
//to change the actionbar color
getSupportActionBar().setBackgroundDrawable(newColor);
}
这是我尝试保存和恢复列表视图的代码:
@Override
public void onDestroyView() {
super.onDestroyView();
//try to save listview scroll
index = myList.getFirstVisiblePosition();
View v = myList.getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - myList.getPaddingTop());
index = 1;
//try to save listview items
savedAdapter = adapter;
fromBackStack = true;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myList.setSelectionFromTop(index, top);
myList.setAdapter(savedAdapter);
}
这里是我到目前为止完成的代码:
package com.ngapainya.ngapainya.fragment;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.net.ParseException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import com.ngapainya.ngapainya.R;
import com.ngapainya.ngapainya.activity.volunteer.ContainerActivity;
import com.ngapainya.ngapainya.adapter.HomeAdapter;
import com.ngapainya.ngapainya.fragment.child.DetailPostFragment;
import com.ngapainya.ngapainya.model.Home;
import java.util.ArrayList;
/**
* A simple {@link Fragment} subclass.
*/
public class HomeFragment extends Fragment implements AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener{
private FragmentActivity myContext;
private View myFragmentView;
private ArrayList<Home> filelist;
private ListView myList;
private HomeAdapter adapter;
private SwipeRefreshLayout swipeRefreshLayout;
//try save instance listview
boolean fromBackStack = false;
int index;
int top;
HomeAdapter savedAdapter;
@Override
public void onDestroyView() {
super.onDestroyView();
//try to save listview scroll
index = myList.getFirstVisiblePosition();
View v = myList.getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - myList.getPaddingTop());
index = 1;
//try to save listview items
savedAdapter = adapter;
fromBackStack = true;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myList.setSelectionFromTop(index, top);
myList.setAdapter(savedAdapter);
}
@Override
public void onAttach(Activity activity) {
myContext = (FragmentActivity) activity;
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
myFragmentView = inflater.inflate(R.layout.fragment_home, container, false);
filelist = new ArrayList<Home>();
//dummy data
filelist.add(new Home("post", 1)); //post image
filelist.add(new Home("post", 2)); //post location
filelist.add(new Home("post", 3)); //post url
filelist.add(new Home("post", 4)); //become friend with
filelist.add(new Home("post", 0)); //post status
swipeRefreshLayout = (SwipeRefreshLayout) myFragmentView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
/**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
//do something
swipeRefreshLayout.setRefreshing(false);
}
}
);
myList = (ListView) myFragmentView.findViewById(R.id.list_home);
//myList.setAdapter(new HomeAdapter(myContext, filelist));
adapter = new HomeAdapter(myContext, filelist);
myList.setOnItemClickListener(this);
if(!fromBackStack) {
new RemoteDataTask().execute();
}
return myFragmentView;
}
/**
* This method is called when swipe refresh is pulled down
*/
@Override
public void onRefresh() {
//do something
myList.setAdapter(adapter);
ArrayList<Home> new_filelist = new ArrayList<>();
new_filelist.add(new Home("Post", 4));
filelist.addAll(0, new_filelist);
adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Home tmp = (Home) parent.getItemAtPosition(position);
DetailPostFragment detailPostFragment = new DetailPostFragment();
Bundle args = new Bundle();
switch (tmp.type) {
case 0:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 1:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 2:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 3:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 4:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
}
}
private class RemoteDataTask extends AsyncTask<String, Void, ArrayList<Home>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<Home> doInBackground(String... urls) {
try {
ArrayList<Home> new_filelist = new ArrayList<Home>();
new_filelist.add(new Home("post", 3)); //post url
new_filelist.add(new Home("post", 4)); //become friend with
new_filelist.add(new Home("post", 0)); //post status
filelist.addAll(new_filelist);
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return filelist;
}
@Override
protected void onPostExecute(ArrayList<Home> organization) {
myList.setAdapter(new HomeAdapter(myContext, filelist));
// Create an OnScrollListener
myList.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view,
int scrollState) { // TODO Auto-generated method stub
int threshold = 1;
int count = myList.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (myList.getLastVisiblePosition() >= count
- threshold) {
// Execute LoadMoreDataTask AsyncTask
new LoadMoreDataTask().execute();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
}
}
public class LoadMoreDataTask extends AsyncTask<String, Void, ArrayList<Home>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<Home> doInBackground(String... urls) {
try {
// web service request
ArrayList<Home> new_filelist = new ArrayList<Home>();
new_filelist.add(new Home("post", 0)); //post status
if(new_filelist != null && new_filelist.size() > 0 ){
filelist.addAll(new_filelist);
}
} catch (Exception e) {
e.printStackTrace();
}
return filelist;
}
@Override
protected void onPostExecute(ArrayList<Home> organization) {
int position = myList.getLastVisiblePosition();
adapter = new HomeAdapter(myContext, filelist);
myList.setAdapter(adapter);
adapter.notifyDataSetChanged();
myList.setSelectionFromTop(position, 0);
}
}
}
希望有人能帮帮我,谢谢。
Updated Code
This is my code so far, it works when I try to saved the listview items and its adapter, perhaps this is a bit tricky. If someone has any idea would be appreciated.
package com.ngapainya.ngapainya.fragment;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.net.ParseException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import com.ngapainya.ngapainya.R;
import com.ngapainya.ngapainya.activity.volunteer.ContainerActivity;
import com.ngapainya.ngapainya.adapter.HomeAdapter;
import com.ngapainya.ngapainya.fragment.child.DetailPostFragment;
import com.ngapainya.ngapainya.model.Home;
import java.util.ArrayList;
/**
* A simple {@link Fragment} subclass.
*/
public class HomeFragment extends Fragment implements AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener{
private FragmentActivity myContext;
private View myFragmentView;
private ArrayList<Home> filelist;
private ListView myList;
private HomeAdapter adapter;
private SwipeRefreshLayout swipeRefreshLayout;
/*
* these variables used to restore the listview
* when calling the fragment from backstack
* */
private boolean fromBackStack = false;
private HomeAdapter savedAdapter;
private ArrayList<Home> savedFilelist;
@Override
public void onDestroyView() {
super.onDestroyView();
savedAdapter = adapter;
savedFilelist = filelist;
fromBackStack = true;
Log.e("onDestroyView", "onDestroyView");
}
@Override
public void onAttach(Activity activity) {
myContext = (FragmentActivity) activity;
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
myFragmentView = inflater.inflate(R.layout.fragment_home, container, false);
Log.e("onCreateView", "onCreateView");
swipeRefreshLayout = (SwipeRefreshLayout) myFragmentView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
/**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
/*swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
//do something
swipeRefreshLayout.setRefreshing(false);
}
}
);*/
myList = (ListView) myFragmentView.findViewById(R.id.list_home);
//myList.setAdapter(new HomeAdapter(myContext, filelist));
myList.setOnItemClickListener(this);
filelist = new ArrayList<Home>();
adapter = new HomeAdapter(myContext, filelist);
if(fromBackStack) {
filelist = savedFilelist;
adapter = savedAdapter;
}
new RemoteDataTask().execute();
return myFragmentView;
}
/**
* This method is called when swipe refresh is pulled down
*/
@Override
public void onRefresh() {
ArrayList<Home> new_filelist = new ArrayList<>();
new_filelist.add(new Home("Post", 4));
filelist.addAll(0, new_filelist);
adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
Log.e("onRefresh", "onRefresh");
}
/*
* This method is called whenever the listview item is clicked
* */
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Home tmp = (Home) parent.getItemAtPosition(position);
DetailPostFragment detailPostFragment = new DetailPostFragment();
Bundle args = new Bundle();
switch (tmp.type) {
case 0:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 1:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 2:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 3:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 4:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
}
}
/*
* This method is called in onCreateView method
* Used to load data from server and populate them into
* the listview
* */
private class RemoteDataTask extends AsyncTask<String, Void, ArrayList<Home>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<Home> doInBackground(String... urls) {
try {
ArrayList<Home> new_filelist = new ArrayList<Home>();
//dummy data
new_filelist.add(new Home("post", 1)); //post image
new_filelist.add(new Home("post", 2)); //post location
new_filelist.add(new Home("post", 3)); //post url
new_filelist.add(new Home("post", 4)); //become friend with
new_filelist.add(new Home("post", 0)); //post status
new_filelist.add(new Home("post", 3)); //post url
new_filelist.add(new Home("post", 4)); //become friend with
new_filelist.add(new Home("post", 0)); //post status
filelist.addAll(new_filelist);
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return filelist;
}
@Override
protected void onPostExecute(ArrayList<Home> organization) {
myList.setAdapter(adapter);
// Create an OnScrollListener
myList.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view,
int scrollState) { // TODO Auto-generated method stub
int threshold = 1;
int count = myList.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (myList.getLastVisiblePosition() >= count
- threshold) {
// Execute LoadMoreDataTask AsyncTask
new LoadMoreDataTask().execute();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
}
}
/*
* This method is called when the listview pulled down
* it will trigger this method to load more items from server
* */
public class LoadMoreDataTask extends AsyncTask<String, Void, ArrayList<Home>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<Home> doInBackground(String... urls) {
try {
// web service request
ArrayList<Home> new_filelist = new ArrayList<Home>();
new_filelist.add(new Home("post", 0)); //post status
new_filelist.add(new Home("post", 1));
if(new_filelist != null && new_filelist.size() > 0 ){
filelist.addAll(new_filelist);
}
} catch (Exception e) {
e.printStackTrace();
}
return filelist;
}
@Override
protected void onPostExecute(ArrayList<Home> organization) {
int position = myList.getLastVisiblePosition();
//adapter = new HomeAdapter(myContext, filelist);
myList.setAdapter(adapter);
adapter.notifyDataSetChanged();
myList.setSelectionFromTop(position, 0);
}
}
}
我终于明白了...
我不知道这是否是最好的解决方案,但到目前为止它对我有用。
我只需要一个方法和几个变量,就像这样。
@Override
public void onDestroyView() {
super.onDestroyView();
savedAdapter = adapter;
savedFilelist = filelist;
fromBackStack = true;
Log.e("onDestroyView", "onDestroyView");
}
非常感谢。
我曾尝试搜索此问题,但找不到任何解决方案。 我在片段中保存 ListView 项目时遇到问题。情况是我有几个片段
let say FRAGMENT A, FRAGMENT B and FRAGMENT C, and FRAGMENT A has a listview, the item of the listview can be changed when user scroll (just like timeline in social media apps). When I change the fragment A, I used addToBackStack(null) method.
问题是,如果按下后退按钮,如何保存列表视图并恢复它?
onSaveInstanceState() is never called because the Activity host is never killed, only change the fragment using this:
public void changeFragment(Fragment fragment, ColorDrawable colorDrawable){
Fragment newFrag = fragment;
ColorDrawable newColor = colorDrawable;
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped){ //fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_fragment, fragment);
ft.addToBackStack(backStateName);
ft.commit();
}
//to change the actionbar color
getSupportActionBar().setBackgroundDrawable(newColor);
}
这是我尝试保存和恢复列表视图的代码:
@Override
public void onDestroyView() {
super.onDestroyView();
//try to save listview scroll
index = myList.getFirstVisiblePosition();
View v = myList.getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - myList.getPaddingTop());
index = 1;
//try to save listview items
savedAdapter = adapter;
fromBackStack = true;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myList.setSelectionFromTop(index, top);
myList.setAdapter(savedAdapter);
}
这里是我到目前为止完成的代码:
package com.ngapainya.ngapainya.fragment;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.net.ParseException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import com.ngapainya.ngapainya.R;
import com.ngapainya.ngapainya.activity.volunteer.ContainerActivity;
import com.ngapainya.ngapainya.adapter.HomeAdapter;
import com.ngapainya.ngapainya.fragment.child.DetailPostFragment;
import com.ngapainya.ngapainya.model.Home;
import java.util.ArrayList;
/**
* A simple {@link Fragment} subclass.
*/
public class HomeFragment extends Fragment implements AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener{
private FragmentActivity myContext;
private View myFragmentView;
private ArrayList<Home> filelist;
private ListView myList;
private HomeAdapter adapter;
private SwipeRefreshLayout swipeRefreshLayout;
//try save instance listview
boolean fromBackStack = false;
int index;
int top;
HomeAdapter savedAdapter;
@Override
public void onDestroyView() {
super.onDestroyView();
//try to save listview scroll
index = myList.getFirstVisiblePosition();
View v = myList.getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - myList.getPaddingTop());
index = 1;
//try to save listview items
savedAdapter = adapter;
fromBackStack = true;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
myList.setSelectionFromTop(index, top);
myList.setAdapter(savedAdapter);
}
@Override
public void onAttach(Activity activity) {
myContext = (FragmentActivity) activity;
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
myFragmentView = inflater.inflate(R.layout.fragment_home, container, false);
filelist = new ArrayList<Home>();
//dummy data
filelist.add(new Home("post", 1)); //post image
filelist.add(new Home("post", 2)); //post location
filelist.add(new Home("post", 3)); //post url
filelist.add(new Home("post", 4)); //become friend with
filelist.add(new Home("post", 0)); //post status
swipeRefreshLayout = (SwipeRefreshLayout) myFragmentView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
/**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
//do something
swipeRefreshLayout.setRefreshing(false);
}
}
);
myList = (ListView) myFragmentView.findViewById(R.id.list_home);
//myList.setAdapter(new HomeAdapter(myContext, filelist));
adapter = new HomeAdapter(myContext, filelist);
myList.setOnItemClickListener(this);
if(!fromBackStack) {
new RemoteDataTask().execute();
}
return myFragmentView;
}
/**
* This method is called when swipe refresh is pulled down
*/
@Override
public void onRefresh() {
//do something
myList.setAdapter(adapter);
ArrayList<Home> new_filelist = new ArrayList<>();
new_filelist.add(new Home("Post", 4));
filelist.addAll(0, new_filelist);
adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Home tmp = (Home) parent.getItemAtPosition(position);
DetailPostFragment detailPostFragment = new DetailPostFragment();
Bundle args = new Bundle();
switch (tmp.type) {
case 0:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 1:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 2:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 3:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 4:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
}
}
private class RemoteDataTask extends AsyncTask<String, Void, ArrayList<Home>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<Home> doInBackground(String... urls) {
try {
ArrayList<Home> new_filelist = new ArrayList<Home>();
new_filelist.add(new Home("post", 3)); //post url
new_filelist.add(new Home("post", 4)); //become friend with
new_filelist.add(new Home("post", 0)); //post status
filelist.addAll(new_filelist);
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return filelist;
}
@Override
protected void onPostExecute(ArrayList<Home> organization) {
myList.setAdapter(new HomeAdapter(myContext, filelist));
// Create an OnScrollListener
myList.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view,
int scrollState) { // TODO Auto-generated method stub
int threshold = 1;
int count = myList.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (myList.getLastVisiblePosition() >= count
- threshold) {
// Execute LoadMoreDataTask AsyncTask
new LoadMoreDataTask().execute();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
}
}
public class LoadMoreDataTask extends AsyncTask<String, Void, ArrayList<Home>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<Home> doInBackground(String... urls) {
try {
// web service request
ArrayList<Home> new_filelist = new ArrayList<Home>();
new_filelist.add(new Home("post", 0)); //post status
if(new_filelist != null && new_filelist.size() > 0 ){
filelist.addAll(new_filelist);
}
} catch (Exception e) {
e.printStackTrace();
}
return filelist;
}
@Override
protected void onPostExecute(ArrayList<Home> organization) {
int position = myList.getLastVisiblePosition();
adapter = new HomeAdapter(myContext, filelist);
myList.setAdapter(adapter);
adapter.notifyDataSetChanged();
myList.setSelectionFromTop(position, 0);
}
}
}
希望有人能帮帮我,谢谢。
Updated Code This is my code so far, it works when I try to saved the listview items and its adapter, perhaps this is a bit tricky. If someone has any idea would be appreciated.
package com.ngapainya.ngapainya.fragment;
import android.app.Activity;
import android.graphics.drawable.ColorDrawable;
import android.net.ParseException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import com.ngapainya.ngapainya.R;
import com.ngapainya.ngapainya.activity.volunteer.ContainerActivity;
import com.ngapainya.ngapainya.adapter.HomeAdapter;
import com.ngapainya.ngapainya.fragment.child.DetailPostFragment;
import com.ngapainya.ngapainya.model.Home;
import java.util.ArrayList;
/**
* A simple {@link Fragment} subclass.
*/
public class HomeFragment extends Fragment implements AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener{
private FragmentActivity myContext;
private View myFragmentView;
private ArrayList<Home> filelist;
private ListView myList;
private HomeAdapter adapter;
private SwipeRefreshLayout swipeRefreshLayout;
/*
* these variables used to restore the listview
* when calling the fragment from backstack
* */
private boolean fromBackStack = false;
private HomeAdapter savedAdapter;
private ArrayList<Home> savedFilelist;
@Override
public void onDestroyView() {
super.onDestroyView();
savedAdapter = adapter;
savedFilelist = filelist;
fromBackStack = true;
Log.e("onDestroyView", "onDestroyView");
}
@Override
public void onAttach(Activity activity) {
myContext = (FragmentActivity) activity;
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
myFragmentView = inflater.inflate(R.layout.fragment_home, container, false);
Log.e("onCreateView", "onCreateView");
swipeRefreshLayout = (SwipeRefreshLayout) myFragmentView.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
/**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
/*swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
//do something
swipeRefreshLayout.setRefreshing(false);
}
}
);*/
myList = (ListView) myFragmentView.findViewById(R.id.list_home);
//myList.setAdapter(new HomeAdapter(myContext, filelist));
myList.setOnItemClickListener(this);
filelist = new ArrayList<Home>();
adapter = new HomeAdapter(myContext, filelist);
if(fromBackStack) {
filelist = savedFilelist;
adapter = savedAdapter;
}
new RemoteDataTask().execute();
return myFragmentView;
}
/**
* This method is called when swipe refresh is pulled down
*/
@Override
public void onRefresh() {
ArrayList<Home> new_filelist = new ArrayList<>();
new_filelist.add(new Home("Post", 4));
filelist.addAll(0, new_filelist);
adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
Log.e("onRefresh", "onRefresh");
}
/*
* This method is called whenever the listview item is clicked
* */
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Home tmp = (Home) parent.getItemAtPosition(position);
DetailPostFragment detailPostFragment = new DetailPostFragment();
Bundle args = new Bundle();
switch (tmp.type) {
case 0:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 1:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 2:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 3:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
case 4:
args.putInt("postType", tmp.type);
detailPostFragment.setArguments(args);
((ContainerActivity) getActivity()).changeFragment(detailPostFragment, new ColorDrawable(getResources().getColor(R.color.ColorPrimary)));
break;
}
}
/*
* This method is called in onCreateView method
* Used to load data from server and populate them into
* the listview
* */
private class RemoteDataTask extends AsyncTask<String, Void, ArrayList<Home>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<Home> doInBackground(String... urls) {
try {
ArrayList<Home> new_filelist = new ArrayList<Home>();
//dummy data
new_filelist.add(new Home("post", 1)); //post image
new_filelist.add(new Home("post", 2)); //post location
new_filelist.add(new Home("post", 3)); //post url
new_filelist.add(new Home("post", 4)); //become friend with
new_filelist.add(new Home("post", 0)); //post status
new_filelist.add(new Home("post", 3)); //post url
new_filelist.add(new Home("post", 4)); //become friend with
new_filelist.add(new Home("post", 0)); //post status
filelist.addAll(new_filelist);
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return filelist;
}
@Override
protected void onPostExecute(ArrayList<Home> organization) {
myList.setAdapter(adapter);
// Create an OnScrollListener
myList.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view,
int scrollState) { // TODO Auto-generated method stub
int threshold = 1;
int count = myList.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (myList.getLastVisiblePosition() >= count
- threshold) {
// Execute LoadMoreDataTask AsyncTask
new LoadMoreDataTask().execute();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
}
}
/*
* This method is called when the listview pulled down
* it will trigger this method to load more items from server
* */
public class LoadMoreDataTask extends AsyncTask<String, Void, ArrayList<Home>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<Home> doInBackground(String... urls) {
try {
// web service request
ArrayList<Home> new_filelist = new ArrayList<Home>();
new_filelist.add(new Home("post", 0)); //post status
new_filelist.add(new Home("post", 1));
if(new_filelist != null && new_filelist.size() > 0 ){
filelist.addAll(new_filelist);
}
} catch (Exception e) {
e.printStackTrace();
}
return filelist;
}
@Override
protected void onPostExecute(ArrayList<Home> organization) {
int position = myList.getLastVisiblePosition();
//adapter = new HomeAdapter(myContext, filelist);
myList.setAdapter(adapter);
adapter.notifyDataSetChanged();
myList.setSelectionFromTop(position, 0);
}
}
}
我终于明白了... 我不知道这是否是最好的解决方案,但到目前为止它对我有用。 我只需要一个方法和几个变量,就像这样。
@Override
public void onDestroyView() {
super.onDestroyView();
savedAdapter = adapter;
savedFilelist = filelist;
fromBackStack = true;
Log.e("onDestroyView", "onDestroyView");
}
非常感谢。