您的位置:首页 > 其它

较复杂的ListView

2015-07-04 00:00 197 查看
摘要: ListView / convertView / ViewHolder

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();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息