java - La vista de lista de desplazamiento sin fin no funciona
android json (2)
Para mostrar solo 10 elementos por primera vez en
ListView
y mostrar más elementos en el desplazamiento, siga los siguientes pasos:
PASO 1:
Cree un método
chunkList
que divida
ArrayList
en partes de tamaño 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;
}
PASO 2:
Cree
ArrayList
y un contador que muestre la parte actual:
private boolean isLoadingMore=false;
Handler mHandler = new Handler();
List<ArrayList<HashMap<String,String>>> mainArrayList;
private int count=0;
PASO 3:
en
onPostExecute
break
result
y muestra datos en 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);
}
}
PASO 4: Cree el método addAll en el Adaptador para agregar datos en la fuente de datos actual:
public void addAll(ArrayList<HashMap<String,String>> moreData){
this.listData.addAll(moreData);
this.notifyDataSetChanged();
}
PASO 5:
En
onLoadMore
cargue más datos en 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;
}
}
}
};
Estoy desarrollando una aplicación. En mi aplicación estoy usando listview para mostrar datos de json. Todos los datos se muestran perfectamente. Pero lo que quiero es mostrar primero los 10 objetos y luego cargar los elementos, y luego se mostrarán los 10 restantes. Mi respuesta json es como se da a continuación.
{
"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
clase pública CustomAdapterSent extiende 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;
}
}
Archivo XML:
<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>
Para tener un AdapterView (como ListView o GridView) que carga automáticamente más elementos a medida que el usuario se desplaza por los elementos (también conocido como desplazamiento infinito). Esto se realiza activando una solicitud de más datos una vez que el usuario cruza el umbral de los elementos restantes antes de llegar al final. Cada AdapterView tiene soporte para vincularse a los eventos OnScrollListener que se activan cada vez que un usuario se desplaza por la colección. Usando este sistema, podemos definir un EndlessScrollListener básico que admite la mayoría de los casos de uso creando nuestra propia clase que extiende OnScrollListener.
Puede encontrar más información sobre esto en los siguientes enlaces:
Desplazamiento sin fin ListView en Android
Desplazamiento sin fin con AdapterViews
Vista de lista de desplazamiento infinito
En esta respuesta SO se muestra un enfoque más simple para agregar datos en una vista de lista : Lista sin fin de Android
Espero que esto ayude ...