package com.ittianyu.mobileguard.fragment.base; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import com.ittianyu.mobileguard.R; import com.ittianyu.mobileguard.dao.AppLockDao; import com.ittianyu.mobileguard.domain.AppInfoBean; import com.ittianyu.mobileguard.engine.AppManagerEngine; import java.util.ArrayList; import java.util.List; /** * a ListView to show apps */ public abstract class BaseAppLockFragment extends Fragment { // constants private static final long DURATION_REMOVE = 200; // view private ListView lvApp; private ProgressBar pvLoading; // data private List<AppInfoBean> apps = new ArrayList<>(); private AppAdapter adapter = new AppAdapter(); // thread operation private Thread initDataThread; /** * inflate view and bind view * * @param inflater * @param container * @param savedInstanceState * @return */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_app_lock, container, false); // bind view lvApp = (ListView) view.findViewById(R.id.lv_app); pvLoading = (ProgressBar) view.findViewById(R.id.pb_loading); initEvent(); return view; } /** * init event */ private void initEvent() { lvApp.setAdapter(adapter); } /** * init data */ @Override public void onResume() { super.onResume(); initData(); } /** * init data */ private void initData() { // if the thread is running, no need to start a new thread if (null != initDataThread && initDataThread.isAlive()) { return; } // prevent violence click final FragmentActivity context = getActivity(); if (null == context) return; // start a new thread to init data initDataThread = new Thread() { @Override public void run() { // get all apps List<AppInfoBean> apps = AppManagerEngine.getInstalledAppInfo(context, null); initAppsAndRefreshUi(context, apps); } }; initDataThread.start(); } /** * distribute the apps and refresh ListView * * @param context * @param appsInfo */ private void initAppsAndRefreshUi(final FragmentActivity context, final List<AppInfoBean> appsInfo) { // refresh ui need run on ui thread // and remember the change data should'n in background thread context.runOnUiThread(new Runnable() { @Override public void run() { // clear data apps.clear(); // distribute apps AppLockDao dao = new AppLockDao(context); for (AppInfoBean app : appsInfo) { // if in locked list if (isNeededApp(dao, app.getPackageName())) { // add to locked list apps.add(app); } } // notify update ListView adapter.notifyDataSetChanged(); // hide loading bar pvLoading.setVisibility(View.GONE); } }); } /** * if the app is need app, it will add to list and show * * @param dao AppLockDao * @param packageName the package name * @return The app will be add to list and show if true */ protected abstract boolean isNeededApp(AppLockDao dao, String packageName); /** * app adapter */ private class AppAdapter extends BaseAdapter { @Override public int getCount() { return apps.size(); } @Override public AppInfoBean getItem(int position) { return apps.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup parent) { final Context context = getActivity(); View view = null; ViewItem item = null; // if no cache if (null == convertView) { // create view and ViewItem view = View.inflate(context, R.layout.item_app_lock_lv, null); item = new ViewItem(); // set view item view.setTag(item); // bind child view item.ivIcon = (ImageView) view.findViewById(R.id.iv_icon); item.ivEvent = (ImageView) view.findViewById(R.id.iv_unlock); item.tvTitle = (TextView) view.findViewById(R.id.tv_title); } else { view = convertView; item = (ViewItem) view.getTag(); } // get item final AppInfoBean bean = getItem(position); // set value item.tvTitle.setText(bean.getName()); item.ivIcon.setImageDrawable(bean.getIcon()); // set image and listener setEventImageAndListener(item.ivEvent, bean.getPackageName(), position, view); return view; } } /** * It will be call when ListView call getView() * You can use defaultSetEventImageAndListener() to implement the base function * * @param ivEvent the ImageView which in right of item * @param packageName the current app package name * @param position the current app position * @param rootView the item root view */ protected abstract void setEventImageAndListener(ImageView ivEvent, final String packageName, final int position, View rootView); /** * the default scheme for setEventImageAndListener * * @param ivEvent the ImageView which in right of item * @param packageName the current app package name * @param position the current app position * @param imageId the ivEvent drawable id * @param isAdd It will add to db if true, otherwise remove from db * @param rootView the item root view */ protected void defaultSetEventImageAndListener(final ImageView ivEvent, final String packageName, final int position, int imageId, final boolean isAdd, final View rootView) { ivEvent.setImageResource(imageId); // set on item click listener for unlocking app ivEvent.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int fromX, toX; if (isAdd) { // translate to right fromX = 0; toX = 1; } else { // translate to left fromX = 0; toX = -1; } // remove animation TranslateAnimation animation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, fromX,// from x Animation.RELATIVE_TO_SELF, toX,// to x Animation.RELATIVE_TO_SELF, 0,// from y Animation.RELATIVE_TO_SELF, 0);// to y animation.setDuration(DURATION_REMOVE); // register listener, call remove method when animation end animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { // if success to lock apps.remove(position); // refresh ui adapter.notifyDataSetChanged(); } @Override public void onAnimationRepeat(Animation animation) { } }); AppLockDao dao = new AppLockDao(getActivity()); boolean isSuccess = false; if (isAdd) { isSuccess = dao.insert(packageName); } else { isSuccess = dao.delete(packageName); } // if success, start animation if(isSuccess) { // start animation and it will remove the root view when animation end rootView.startAnimation(animation); } } }); } /** * used for cache child view */ private static class ViewItem { private ImageView ivIcon; private TextView tvTitle; private ImageView ivEvent; } }