android ListView 动态分页加载数据
2017-06-17 17:50
423 查看
参考文章:
http://blog.csdn.net/zimo2013/article/details/10263339
http://blog.csdn.net/zimo2013/article/details/12253301
用ListView显示数据时,列表中数据量大时,加载和处理时间会明显变长,如果等到把所有数据都处理加载完成再显示出来,那程序的UI就非常糟糕了,很可能会随数据量的变大而变慢,这样的界面很不友好,我们无法接受。
废话说完了,那怎么解决这个的问题呢?
动态加载,分页加载。我不能在UI线程中做大量的读取、处理数据的动作,而是另开一个线程来做这件事。但是这样并不能保证显示及时,因为数据大时,时间仍会很长,怎么办,那我先处理一部分,先显示出来它们,后台再继续处理后面的数据,处理一部分,加载一部分。
这就要用到Adapter和loader 类。
Adapter 需要loader 类来给它提供数据,它才给使listView 显示出来。
所以下面是loader 类,这个类是在后台读取并处理数据,处理完成一部分,给Adapter 来显示。但是分步处理这个过程需要借助
http://blog.csdn.net/zimo2013/article/details/10263339
http://blog.csdn.net/zimo2013/article/details/12253301
用ListView显示数据时,列表中数据量大时,加载和处理时间会明显变长,如果等到把所有数据都处理加载完成再显示出来,那程序的UI就非常糟糕了,很可能会随数据量的变大而变慢,这样的界面很不友好,我们无法接受。
废话说完了,那怎么解决这个的问题呢?
动态加载,分页加载。我不能在UI线程中做大量的读取、处理数据的动作,而是另开一个线程来做这件事。但是这样并不能保证显示及时,因为数据大时,时间仍会很长,怎么办,那我先处理一部分,先显示出来它们,后台再继续处理后面的数据,处理一部分,加载一部分。
这就要用到Adapter和loader 类。
static class AppsListItem{ public Drawable icon = null; public String appLabel = ""; public String summary = ""; public String packageName = ""; public int uid = -1; public int permCount = 0; public String key = ""; } public static class AppListAdapter extends BaseAdapter { Activity mActivity; LayoutInflater mLayoutInflater; PackageManager mPackageManager; List<AppsListItem> mAppList; public AppListAdapter(Activity activity){ mActivity = activity; mLayoutInflater = activity.getLayoutInflater(); mPackageManager = activity.getPackageManager(); mAppList = new ArrayList<AppsListItem>(); } @Override public int getCount() { return (mAppList == null)? 0 : mAppList.size(); } @Override public Object getItem(int position) { return mAppList.get(position); } public Object getItem(String packageName){ for(AppsListItem appInfo : mAppList){ if(appInfo.packageName.equals(packageName)){ return appInfo; } } return null; } @Override public long getItemId(int position) { return position; } class ViewHolder{ ImageView appIcon; TextView appName; TextView summary; } @Override public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder viewHolder; if(convertView == null) { convertView = mLayoutInflater.inflate(R.layout.permission_preference_layout2, parent, false); viewHolder = new ViewHolder(); viewHolder.appIcon = ((ImageView) convertView.findViewById(R.id.appIcon)); viewHolder.appName = ((TextView) convertView.findViewById(R.id.appName)); viewHolder.summary = ((TextView) convertView.findViewById(R.id.summary)); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } final AppsListItem appInfo = mAppList.get(position); viewHolder.appIcon.setImageDrawable(appInfo.icon); viewHolder.appName.setText(appInfo.appLabel); viewHolder.summary.setText(appInfo.summary); return convertView; } public void setData(List<AppsListItem> selectedAppList) { mAppList.clear(); if (selectedAppList != null) { Log.w(TAG,"APP list size "+selectedAppList.size()); mAppList = selectedAppList; } notifyDataSetChanged(); } public void addData(List<AppsListItem> selectedAppList) { if (selectedAppList != null) { Log.w(TAG,"APP list size "+selectedAppList.size()); mAppList.addAll(selectedAppList); } notifyDataSetChanged(); } public void removeItem(String packageName){ AppsListItem item = (AppsListItem)getItem(packageName); if(item != null){ mAppList.remove(item); notifyDataSetChanged(); } } public void removeItem(int position){ if(position < mAppList.size()){ mAppList.remove(position); notifyDataSetChanged(); } } public void addData(AppsListItem item) { if (item != null) { Log.w(LISTTAG,"add package "+item.packageName+" Label: "+item.appLabel); mAppList.add(item); } notifyDataSetChanged(); } }怎么用这个Adapter 呢,
onStart(){ ... listview.setAdapter(mAdapter); listview.setSelectionFromTop(mSaveIndex, mtop); listview.setOnScrollChangeListener(new View.OnScrollChangeListener() { @Override public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { //mAdapter.notifyDataSetChanged(); } }); listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mSaveIndex = listview.getFirstVisiblePosition(); View v = listview.getChildAt(0); mtop = (v == null) ? 0 : (v.getTop() - listview.getPaddingTop()); AppsListItem appinfo = (AppsListItem)mAdapter.getItem(position); if(appinfo != null){ final String mPackageName = appinfo.packageName; final int mUid = appinfo.uid; int permCnt = appinfo.permCount; Intent sendIntent = new Intent(); sendIntent.setAction("android.intent.action.MANAGE_APP_PERMISSIONS"); sendIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackageName); sendIntent.putExtra(Intent.EXTRA_UID, mUid); sendIntent.putExtra("hideInfoButton", true); startActivity(sendIntent); } } }); }
Adapter 需要loader 类来给它提供数据,它才给使listView 显示出来。
所以下面是loader 类,这个类是在后台读取并处理数据,处理完成一部分,给Adapter 来显示。但是分步处理这个过程需要借助
LoaderManager的。
/** * A custom Loader that loads all of the installed applications. */ public static class AppListLoader extends AsyncTaskLoader<List<AppsListItem>> { private int mCount = 0; private static int mOldCount = 0; private static int mSize = 0; private List<AppsListItem> items = null; private static List<ApplicationInfo> apps = new ArrayList<>(); Boolean second = false; String SHAREDPREFERENCE_INSTALLED_PERMISSION_INFO = "PermissionInfos"; public AppListLoader(Context context,int count) { super(context); mCount = count; Log.w(LISTTAG,"mCount "+mCount+" mOldCount "+mOldCount); if(items == null) { items = new ArrayList<AppsListItem>(); } //You Should confirm FIRSTLOAD (11) num diff from others (5) if(mCount ==FIRSTLOAD ) { mOldCount = 0; } } @Override public List<AppsListItem> loadInBackground() { Log.w(LISTTAG,"===============loadInBackground ================="); return buildList(); } @Override protected void onStartLoading() { Log.w(LISTTAG,"===============onStartLoading ================="); forceLoad(); } public List<AppsListItem> buildList() { int permcount = 0; ApplicationInfo appInfo; //Context context = getContext(); PackageManager pm = mContext.getPackageManager(); int index = 0; CtaUtils mCtaUtils = new CtaUtils(mContext); if(apps.size()==0 ) { apps = pm.getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES);//Utils.getAllInstalledApplications(context); } mSize = apps.size(); //Log.w(LISTTAG,"mCount "+mCount+" mOldCount "+mOldCount+" mSize "+mSize); SharedPreferences permissionInfos = mContext.getSharedPreferences(SHAREDPREFERENCE_INSTALLED_PERMISSION_INFO, 0); SharedPreferences.Editor editor = permissionInfos.edit(); for(int i=0;i<mSize;i++){ index = mOldCount+i; if(index <mSize) { appInfo = apps.get(index); if(shouldSkipFirst(pm,appInfo)){ //Log.w(LISTTAG, "shouldSkipFirst I " + i+" index" +index); continue; } String preKey = appInfo.packageName + "|" + appInfo.uid; permcount = permissionInfos.getInt(preKey, -1); if (permcount < 0) { //Log.w(LISTTAG, "getCount I " + i+" index "+index); permcount = getPermissionCountInner(appInfo.packageName); permcount = permcount + mCtaUtils.getCTARecords(appInfo.uid, appInfo.packageName); editor.putInt(preKey, permcount); editor.commit(); } if (shouldSkip( permcount)) { //Log.w(LISTTAG, "shouldSkip I " + i+" index" +index); continue; } AppsListItem item = new AppsListItem(); item.appLabel = appInfo.loadLabel(pm).toString(); item.packageName = appInfo.packageName; item.uid = appInfo.uid; item.icon = appInfo.loadIcon(pm); item.permCount = permcount; item.summary = "" + permcount + mContext.getResources().getString(R.string.permission_count); item.key = appInfo.packageName + "|" + appInfo.uid; if (item.icon == null) { item.icon = mContext.getResources().getDrawable(android.R.drawable.sym_def_app_icon); } items.add(item); mCount--; if(mCount==0) break; }else{ Log.e(LISTTAG, "Out of index! mOldCount " + mOldCount+" i "+i+" mSize "+mSize); loadcomplete = true; apps.clear(); break; } } //Log.w(LISTTAG,"index "+index+" mCount "+mCount); mOldCount = (index+1); /* try { Collections.sort(items, APP_COMPARATOR); } catch (Exception e) { }*/ return items; } private int getPermissionCountInner(String packageName ){ int cnt = 0; mPermSet.clear(); PackageInfo mPackageInfo = getPackageInfo(getContext(), packageName); if(mPackageInfo ==null || mPackageInfo.requestedPermissions == null) { return cnt; } for (String requestedPerm : mPackageInfo.requestedPermissions) { //Log.w(TAG,"requestedPerm "+requestedPerm); PermissionInfo permInfo = null; try { permInfo = mContext.getPackageManager().getPermissionInfo(requestedPerm, 0); } catch (PackageManager.NameNotFoundException e) { //Log.w(TAG, "NameNotFoundException "+e.getLocalizedMessage()); } if (permInfo != null && permInfo.group != null) { mPermSet.add(permInfo.group); } } for(String groupName : mPermSet){ switch(groupName){ case PERMISSION_CALENDER_GROUP_NAME: case PERMISSION_STORAGE_GROUP_NAME: case PERMISSION_BODY_SENSORS_GROUP_NAME: case PERMISSION_SMS_GROUP_NAME: case PERMISSION_CONTACTS_GROUP_NAME: case PERMISSION_PHONE_GROUP_NAME: case PERMISSION_CAMERA_GROUP_NAME: case PERMISSION_MICROPHONE_GROUP_NAME: case PERMISSION_LOCATION_GROUP_NAME: cnt++; break; } } return cnt; } /* public static final Comparator<AppsListItem> APP_COMPARATOR = new Comparator<AppsListItem>() { @Override public int compare(AppsListItem item1, AppsListItem item2) { String temp = "" + item2.switchState; int res = temp.compareTo("" + item1.switchState); if(res == 0){ if(item2.suggestOpenText.compareTo(item1.suggestOpenText) == 0) { res = 0; }else if(item2.suggestOpenText.compareTo(item1.suggestOpenText) > 0){ res = 1; }else{ res = -1; } } return res; } };*/ }
所以我们需要实现LoaderManager 的几个callback: onCreateLoader, onLoadFinished, onLoaderReset 在这几个callback中来把loader
public class MyActivity extends FrameFrgment implements LoaderManager.LoaderCallbacks<List<MyActivity.AppsListItem>> { onCreate{ ... mAdapter= new AppListAdapter(getActivity()); Bundle args = new Bundle(); args.putInt(loadcount,FIRSTLOAD); getLoaderManager().initLoader(0, args, this); ...} ... private void restartLoader(){ Bundle args = new Bundle(); args.putInt("count",LOADNUM); getLoaderManager().restartLoader(0,args,this); Log.w(TAG,"===============onLoaderReset ================="); } @Override public Loader<List<AppsListItem>> onCreateLoader(int id, Bundle args) { int count = 0; if(args != null) { count = args.getInt(loadcount, 10); } mAppListLoader = new AppListLoader(getActivity(),count); return mAppListLoader; } @Override public void onLoadFinished(Loader<List<AppsListItem>> loader, List<AppsListItem> data) { try { if(mAdapter.getCount()==0) { mAdapter.setData(data); if(!loadcomplete) { //You Should confirm FIRSTLOAD (11) num diff from others (5) restartLoader(); } } else { mAdapter.addData(data); if(!loadcomplete) { //You Should confirm FIRSTLOAD (11) num diff from others (5) restartLoader(); } } setLoading(false,true); }catch (Exception err){ Log.d(LISTTAG, "AppAutoStartList-->onLoadFinished", err); } } @Override public void onLoaderReset(Loader<List<AppsListItem>> loader) { // Clear the data in the adapter. //mAdapter.setData(null); }
相关文章推荐
- Android实现listview动态加载数据分页的两种方法
- Android中ListView分页加载 动态加载数据
- android中listview分页加载数据
- Android中ListView分页加载数据
- Android腾讯微博客户端开发5:利用FootView实现ListView滑动动态加载实现分页
- Android中ListView分页加载数据
- Android中ListView分页加载数据
- 【android动态布局】之【ListView动态加载数据模板(使用xml布局)】
- Android中ListView分页加载数据
- Android腾讯微博客户端开发5:利用FootView实现ListView滑动动态加载实现分页
- android中listview分页加载数据
- Android中ListView分页加载数据
- android左右滑动加载分页以及动态加载数据
- android左右滑动加载分页以及动态加载数据
- Android中使用Listview动态加载数据
- Android中ListView动态加载数据
- android中listview分页加载数据
- android中listview分页加载数据
- Android中ListView分页加载数据
- Android中ListView分页加载数据