问题
I am developing one application. In my app I am using listview to display data from json. All the data display perfectly. But what I want is, to display first 10 objects and then loading items should show and then remaining 10 will display. My json response is as given below.
{
\"interestsent\":
[
{
\"interestsent_user_id\":369,
\"name\":\"abc\",
\"profile_id\":\"686317\",
\"image\":\"\",
},
{
\"interestsent_user_id\":369,
\"name\":\"def\",
\"profile_id\":\"686318\",
\"image\":\"\",
},
{
\"interestsent_user_id\":369,
\"name\":\"ghi\",
\"profile_id\":\"686319\",
\"image\":\"\",
},
{
\"interestsent_user_id\":369,
\"name\":\"jkl\",
\"profile_id\":\"686320\",
\"image\":\"\",
},
{
\"interestsent_user_id\":369,
\"name\":\"mno\",
\"profile_id\":\"686321\",
\"image\":\"\",
},
{
\"interestsent_user_id\":369,
\"name\":\"pqr\",
\"profile_id\":\"686322\",
\"image\":\"\",
},
.................
.................
]
}
Interestsent.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
INTEREST_SENT_URL = \"http://fshdfh.com/webservice/interestsent?version=apps&user_login_id=00\";
new GetData().execute(\"\");
listview = (ListView) findViewById(R.id.listview);
Log.i(\"DATA\", \"page ::onCreate onCreate onCreate \");
mHandler = new Handler();
listview.setOnScrollListener(new EndlessScrollListener() {
@Override
public void onLoadMore(int page, int totalItemsCount) {
Log.i(\"DATA\", \"page :: \" + page + \" totalItemsCount :: \"
+ totalItemsCount);
mProgressbar = new ProgressDialog(MainActivity.this);
mProgressbar.setMessage(\"Loading...\");
mProgressbar.show();
count++;
if (count < maindata.size()) {
if (adapter != null) {
if (!isLoadingMore) {
isLoadingMore = true;
mHandler.postDelayed(loadMoreRunnable, 1000);
}
}
}
}
});
}
Runnable loadMoreRunnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (count < maindata.size()) {
if (adapter != null) {
adapter.addAll(maindata.get(count));
mHandler.removeCallbacks(loadMoreRunnable);
isLoadingMore = false;
if (mProgressbar.isShowing())
mProgressbar.dismiss();
}
}
}
};
static <T> ArrayList<ArrayList<T>> chunkList(List<T> list, final int L) {
ArrayList<ArrayList<T>> parts = new ArrayList<ArrayList<T>>();
final int N = list.size();
for (int i = 0; i < N; i += L) {
parts.add(new ArrayList<T>(list.subList(i, Math.min(N, i + L))));
}
return parts;
}
private ProgressDialog mProgressbar;
public class GetData extends AsyncTask<String, String, String> {
ArrayList<Integer> data = new ArrayList<Integer>();
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
mProgressbar = new ProgressDialog(MainActivity.this);
mProgressbar.setMessage(\"Loading...\");
mProgressbar.show();
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
ArrayList<ArrayList<Integer>> data = new ArrayList<ArrayList<Integer>>();
ServiceHandler sh = new ServiceHandler();
/*try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
/*for (int i = 0; i < 500; i++) {
data.add(i);
}
return null;*/
String jsonStr = sh.makeServiceCall(INTEREST_SENT_URL, ServiceHandler.GET);
Log.d(\"Response: \", \"> \" + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
interestsent = jsonObj.getJSONArray(INTEREST_SENT);
// looping through All Contacts
for (int i = 0; i < interestsent.length(); i++) {
JSONObject c = interestsent.getJSONObject(i);
// creating new HashMap
// HashMap<ArrayList<Integer> map = new HashMap<Integer>();
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(INTEREST_USER_ID, c.getString(INTEREST_USER_ID));
map.put(INTEREST_SENT_NAME,c.getString(INTEREST_SENT_NAME));
map.put(INTEREST_SENT_PROFILE, c.getString(INTEREST_SENT_PROFILE));
map.put(INTEREST_SENT_IMAGE, c.getString(INTEREST_SENT_IMAGE));
map.put(INTEREST_SENT_CAST, c.getString(INTEREST_SENT_CAST));
map.put(INTEREST_SENT_AGE, c.getString(INTEREST_SENT_AGE)+\" years\");
map.put(INTEREST_SENT_LOCATION, c.getString(INTEREST_SENT_LOCATION));
// adding HashList to ArrayList
data.addAll(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e(\"ServiceHandler\", \"Couldn\'t get any data from the url\");
}
return data;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
maindata = chunkList(data, 50);
Log.i(\"DATA\", \"maindata :: \" + maindata.size());
adapter = new CustomAdapterSent(maindata.get(count),
MainActivity.this);
listview.setAdapter(adapter);
if (mProgressbar.isShowing())
mProgressbar.dismiss();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
EndlessScroolListener.java
public abstract class EndlessScrollListener implements OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 5;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;
public EndlessScrollListener() {
}
public EndlessScrollListener(int visibleThreshold) {
this.visibleThreshold = visibleThreshold;
}
public EndlessScrollListener(int visibleThreshold, int startPage) {
this.visibleThreshold = visibleThreshold;
this.startingPageIndex = startPage;
this.currentPage = startPage;
}
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount)
{
// If the total item count is zero and the previous isn\'t, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) { this.loading = true; }
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if (loading && (totalItemCount > previousTotalItemCount)) {
loading = false;
previousTotalItemCount = totalItemCount;
currentPage++;
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
if (!loading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + visibleThreshold)) {
onLoadMore(currentPage + 1, totalItemCount);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// Don\'t take any action on changed
}
}
CustomAdapterSent.java
public class CustomAdapterSent extends BaseAdapter{
private ArrayList<Integer> mData = new ArrayList<Integer>();
private Context mContext;
private LayoutInflater inflater = null;
private static final String TAG_NAME=\"name\";
private static final String TAG_PROFILE=\"profile_id\";
private static final String TAG_IMAGE=\"image\";
private static final String TAG_CAST=\"cast\";
private static final String TAG_AGE=\"age\";
private static final String TAG_LOCATION=\"location\";
public CustomAdapterSent(ArrayList<Integer> mData, Context mContext) {
this.mContext = mContext;
this.mData = mData;
inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addAll(ArrayList<Integer> mmData) {
this.mData.addAll(mmData);
this.notifyDataSetChanged();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mData.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return mData.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
class ViewHolder {
public TextView txtView;
TextView txtproname;
}
@Override
public View getView(int postion, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
ViewHolder holder;
if (view == null) {
view = inflater.inflate(R.layout.row_layout, null);
holder = new ViewHolder();
///holder.propic = (ImageView) convertView.findViewById(R.id.propicsent);
// holder.txtproname = (TextView) convertView.findViewById(R.id.txtpronameintsent);
//holder.txtproid = (TextView) convertView.findViewById(R.id.txtproidsent);
//holder.txtprofilecast = (TextView) convertView.findViewById(R.id.txtprofilecastintsent);
//holder.txtprofileage = (TextView) convertView.findViewById(R.id.txtprofileageintsent);
// holder.txtprofileplace = (TextView) convertView.findViewById(R.id.txtprofileplaceintsent);
holder.txtView = (TextView) view.findViewById(R.id.no_intsent);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
Log.i(\"DATA\", \"mData.get(postion) :: \" + mData.get(postion));
mData.get(postion);
// holder.txtproname.setText(listData.get(position).get(TAG_NAME));
holder.txtView.setText(\"Index :: \" + Integer.getInteger(TAG_NAME));
return view;
}
}
XML File:
<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"match_parent\"
android:layout_height=\"match_parent\"
android:id=\"@+id/relativemainss\"
android:background=\"@drawable/backg\"
>
<ListView android:id=\"@android:id/list\"
android:layout_height=\"wrap_content\"
android:layout_width=\"wrap_content\"
android:dividerHeight=\"1dp\">
</ListView>
<TextView
android:layout_height=\"wrap_content\"
android:layout_width=\"wrap_content\"
android:layout_centerInParent=\"true\"
android:id=\"@+id/no_intsent\"
android:textColor=\"@android:color/black\"
android:background=\"@drawable/nomessaegborder\" />
<Button
android:layout_height=\"wrap_content\"
android:layout_width=\"wrap_content\"
android:text=\"Load More\"
android:id=\"@+id/buttoloadmoreintsent\"
android:layout_below=\"@android:id/list\" />
</RelativeLayout>
回答1:
To Show only 10 item first time in ListView
and show more items on scroll follow following steps:
STEP 1: Create a chunkList
method which divide ArrayList
in parts of size 10:
static <T> List<ArrayList<T>> chunkList(List<T> list, final int L) {
List<ArrayList<T>> parts = new ArrayList<ArrayList<T>>();
final int N = list.size();
for (int i = 0; i < N; i += L) {
parts.add(new ArrayList<T>(
list.subList(i, Math.min(N, i + L)))
);
}
return parts;
}
STEP 2: Create ArrayList
and a counter which show current part :
private boolean isLoadingMore=false;
Handler mHandler = new Handler();
List<ArrayList<HashMap<String,String>>> mainArrayList;
private int count=0;
STEP 3: In onPostExecute
break result
and show data in ListView:
protected void onPostExecute(ArrayList<HashMap<String,String>> result) {
super.onPostExecute(result);
// your code here...
mainArrayList=chunkList(result,10);
isLoadingMore=false;
count=0;
adapter = new CustomAdapterSent(Interestsent.this,
mainArrayList.get(count));
setListAdapter(adapter);
}
}
STEP 4: Create addAll method in Adapter to append data in current data source :
public void addAll(ArrayList<HashMap<String,String>> moreData){
this.listData.addAll(moreData);
this.notifyDataSetChanged();
}
STEP 5: In onLoadMore
load more data in ListView:
mHandler = new Handler();
listview.setOnScrollListener(new EndlessScrollListener() {
@Override
public void onLoadMore(int page, int totalItemsCount) {
if(count<mainArrayList.size()-1)
{
if(adapter !=null){
count++;
if(!isLoadingMore){
isLoadingMore=true;
mHandler.postDelayed(loadMoreRunnable,1000);
}
}
}
}
});
}
Runnable loadMoreRunnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if(count<mainArrayList.size())
{
if(adapter !=null){
count++;
adapter.addAll(mainArrayList.get(count));
mHandler.removeCallbacks(loadMoreRunnable);
isLoadingMore=false;
}
}
}
};
回答2:
To have an AdapterView (such as a ListView or GridView) that automatically loads more items as the user scrolls through the items (aka infinite scroll). This is done by triggering a request for more data once the user crosses a threshold of remaining items before they've hit the end. Every AdapterView has support for binding to the OnScrollListener events which are triggered whenever a user scrolls through the collection. Using this system, we can define a basic EndlessScrollListener which supports most use cases by creating our own class that extends OnScrollListener.
You can find more about this in the below links :
Endless Scrolling ListView in Android
Endless Scrolling with AdapterViews
Infinite Scrolling List View
A simpler approach of adding data in a listview has been show in this SO answer: Android Endless List
Hope this helps ...
来源:https://stackoverflow.com/questions/28122304/endless-scrolling-listview-not-working