较复杂的ListView

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.text.format.Formatter;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

import com.itcast.mobilesafe01.R;
import com.itcast.mobilesafe01.domain.AppInfo;
import com.itcast.mobilesafe01.engine.AppInfoProvider;

/**
 * 应用管理页面
 * 开发流程:
 * 1. 布局文件
 * 2. 获取可用空间信息
 * 3. 获取已安装应用列表(AppInfoProvider)
 * 4. 加载应用列表,使用listview展示(普通展示)
 * 5. 将用户应用和系统应用分割成两个集合, 让adapter使用这两个集合来展示
 * 6. 增加两个标题(复杂listview展示)
 * 7. 增加一直显示的浮窗
 * 8. 将主线程加载改为异步加载应用列表(可以提前做), 展示加载中的布局
 * 9. 增加popupwindow
 * 10.增加popupwindow动画效果
 * 11.响应弹窗点击事件
 * 12.在点击事件里,分别卸载,启动,分享
 * @author Kevin
 * 
 */
public class AppManagerActivity extends Activity implements OnClickListener {

	private ArrayList<AppInfo> mList;
	private ArrayList<AppInfo> mUserList;// 用户app集合
	private ArrayList<AppInfo> mSystemList;// 系统app集合

	private ListView lvList;
	private AppInfoAdapter mAdapter;

	private TextView tvHeader;// 一直浮在上面的TextView
	private LinearLayout llLoading;
	private PopupWindow mPopupWindow;

	private AppInfo mCurrentInfo;// 当前被点击的对象
	private View mPopupView;
	private AnimationSet mPopupAnimSet;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_app_manager);
		TextView tvRomAvail = (TextView) findViewById(R.id.tv_rom_avail);
		TextView tvSdcardAvail = (TextView) findViewById(R.id.tv_sdcard_avail);

		tvRomAvail.setText("内部存储可用:"
				+ getAvailSpace(Environment.getDataDirectory()
						.getAbsolutePath()));// /data
		tvSdcardAvail.setText("sdcard可用:"
				+ getAvailSpace(Environment.getExternalStorageDirectory()
						.getAbsolutePath()));

		lvList = (ListView) findViewById(R.id.lv_list);
		tvHeader = (TextView) findViewById(R.id.tv_header);
		llLoading = (LinearLayout) findViewById(R.id.ll_loading);

		lvList.setOnScrollListener(new OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {

			}

			// 滑动监听
			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				// firstVisibleItem 第一个可见元素位置
				// visibleItemCount 可见元素数量
				// totalItemCount 元素总数
				if (mUserList != null && mSystemList != null) {
					if (firstVisibleItem >= mUserList.size() + 1) {
						tvHeader.setText("系统应用(" + mSystemList.size() + ")");
					} else {
						tvHeader.setText("用户应用(" + mUserList.size() + ")");
					}
				}
			}
		});

		lvList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				AppInfo info = mAdapter.getItem(position);// 获取被点击的对象
				if (info != null) {// 非标题栏才可以展示
					mCurrentInfo = info;
					showPopupWindow(view);// 将被点击的view对象传递给popupwindow
				}
			}
		});

		initData();
	}

	/**
	 * 展示小弹窗
	 */
	protected void showPopupWindow(View view) {
		if (mPopupWindow == null) {
			mPopupView = View.inflate(this, R.layout.popup_appinfo, null);
			mPopupWindow = new PopupWindow(mPopupView,
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);
			mPopupWindow.setBackgroundDrawable(new ColorDrawable());// 设置空白背景,点击空白/返回键可以消失

			TextView tvUninstall = (TextView) mPopupView
					.findViewById(R.id.tv_uninstall);
			TextView tvLaunch = (TextView) mPopupView
					.findViewById(R.id.tv_launch);
			TextView tvShare = (TextView) mPopupView
					.findViewById(R.id.tv_share);

			tvUninstall.setOnClickListener(this);
			tvLaunch.setOnClickListener(this);
			tvShare.setOnClickListener(this);

			// 渐变动画
			AlphaAnimation animAlpha = new AlphaAnimation(0, 1);
			animAlpha.setDuration(500);

			// 缩放动画
			ScaleAnimation animScale = new ScaleAnimation(0, 1, 0, 1,
					Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,
					0.5f);
			animScale.setDuration(500);

			// 动画集合
			mPopupAnimSet = new AnimationSet(true);
			mPopupAnimSet.addAnimation(animAlpha);
			mPopupAnimSet.addAnimation(animScale);
		}

		// 启动动画
		mPopupView.startAnimation(mPopupAnimSet);
		mPopupWindow.showAsDropDown(view, 60, -view.getHeight());// 展示在被点击view的正下方
	}

	/**
	 * 初始化数据
	 */
	private void initData() {
		llLoading.setVisibility(View.VISIBLE);
		new Thread() {
			@Override
			public void run() {
				mList = AppInfoProvider
						.getInstalledApp(getApplicationContext());// 加载已安装的应用
				mUserList = new ArrayList<AppInfo>();
				mSystemList = new ArrayList<AppInfo>();
				for (AppInfo info : mList) {
					if (info.isUserApp) {
						mUserList.add(info);
					} else {
						mSystemList.add(info);
					}
				}

				// 在主线程运行的简洁方法
				runOnUiThread(new Runnable() {

					@Override
					public void run() {
						mAdapter = new AppInfoAdapter();
						lvList.setAdapter(mAdapter);
						llLoading.setVisibility(View.GONE);
					}
				});
			}
		}.start();
	}

	/**
	 * 获取可用空间
	 */
	private String getAvailSpace(String path) {
		StatFs stat = new StatFs(path);
		long availableBlocks = stat.getAvailableBlocks();// 获取可用存储块的数量
		long blockSize = stat.getBlockSize();// 获取每一个存储块大小
		long availSize = availableBlocks * blockSize;// 可用空间大小
		// Integer.MAX_VALUE = 1.9G
		// Long.MAX_VALUE 8838T
		return Formatter.formatFileSize(this, availSize);// 转成带单位的大小
	}

	class AppInfoAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return mUserList.size() + mSystemList.size() + 2;// 增加两个标题栏
		}

		@Override
		public AppInfo getItem(int position) {
			if (position == 0 || position == mUserList.size() + 1) {// 遇到标题栏,直接返回null
				return null;
			}
			if (position < mUserList.size() + 1) {
				return mUserList.get(position - 1);
			} else {
				return mSystemList.get(position - mUserList.size() - 2);// 需要减掉两个标题栏的占位
			}
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		// 返回布局类型的个数, 就会缓存两种convertView
		@Override
		public int getViewTypeCount() {
			return 2;
		}

		// 根据当前位置,返回相应布局类型, 必须从0开始计算
		@Override
		public int getItemViewType(int position) {
			if (position == 0 || position == mUserList.size() + 1) {// 遇到标题栏
				return 0;
			} else {
				return 1;
			}
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// 首先要判断当前布局类型, 系统会缓存多种convertView, 然后根据当前布局类型,返回对应的convertView
			int type = getItemViewType(position);
			// 根据类型,加载不同布局
			switch (type) {
			case 0:
				HeaderHolder headerHolder;
				if (convertView == null) {
					convertView = View.inflate(getApplicationContext(),
							R.layout.list_item_header, null);
					headerHolder = new HeaderHolder();
					headerHolder.tvHeader = (TextView) convertView
							.findViewById(R.id.tv_header);
					convertView.setTag(headerHolder);
				} else {
					headerHolder = (HeaderHolder) convertView.getTag();
				}

				if (position == 0) {
					headerHolder.tvHeader.setText("用户应用(" + mUserList.size()
							+ ")");
				} else {
					headerHolder.tvHeader.setText("系统应用(" + mSystemList.size()
							+ ")");
				}

				break;
			case 1:
				// View view = null;
				ViewHolder holder = null;
				if (convertView == null) {
					convertView = View.inflate(getApplicationContext(),
							R.layout.list_item_appinfo, null);
					holder = new ViewHolder();
					holder.tvName = (TextView) convertView
							.findViewById(R.id.tv_name);
					holder.tvLocation = (TextView) convertView
							.findViewById(R.id.tv_location);
					holder.ivIcon = (ImageView) convertView
							.findViewById(R.id.iv_icon);

					convertView.setTag(holder);
				} else {
					// view = convertView;
					holder = (ViewHolder) convertView.getTag();
				}

				AppInfo info = getItem(position);
				holder.tvName.setText(info.name);
				holder.ivIcon.setImageDrawable(info.icon);

				if (info.isRom) {
					holder.tvLocation.setText("手机内存");
				} else {
					holder.tvLocation.setText("外置存储器");
				}

				break;
			default:
				break;
			}

			return convertView;
		}

	}

	static class ViewHolder {
		public TextView tvName;
		public TextView tvLocation;
		public ImageView ivIcon;
	}

	static class HeaderHolder {
		public TextView tvHeader;
	}

	@Override
	public void onClick(View v) {
		mPopupWindow.dismiss();// 弹窗消失
		switch (v.getId()) {
		case R.id.tv_uninstall:
			System.out.println("卸载:" + mCurrentInfo.name);
			uninstall();
			break;
		case R.id.tv_launch:
			System.out.println("启动:" + mCurrentInfo.name);
			launchApp();
			break;
		case R.id.tv_share:
			System.out.println("分享:" + mCurrentInfo.name);
			share();
			break;

		default:
			break;
		}
	}

	/**
	 * 分享 调用系统所有可以分享的app, 系统自动生成列表,供用户选择
	 */
	private void share() {
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.setType("text/plain");// 分享纯文本
		intent.putExtra(Intent.EXTRA_TEXT,
				"发现一个很好的应用,赶紧下载哦! 下载地址:https://play.google.com/store/apps/details?id="
						+ mCurrentInfo.packageName);
		startActivity(intent);
	}

	/**
	 * 启动app
	 */
	private void launchApp() {
		// 获取启动页面
		PackageManager pm = getPackageManager();
		Intent intent = pm.getLaunchIntentForPackage(mCurrentInfo.packageName);// 通过包名,获取该app的启动intent
		startActivity(intent);
	}

	/**
	 * 卸载
	 */
	private void uninstall() {
		Intent intent = new Intent(Intent.ACTION_DELETE);
		intent.addCategory(Intent.CATEGORY_DEFAULT);
		intent.setData(Uri.parse("package:" + mCurrentInfo.packageName));
		startActivityForResult(intent, 0);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		// 重新加载数据
		initData();
	}

}




你可能感兴趣的:(ListView高级用法)