12.值动画、测量规则
应用详情安全界面
应用详情描述界面

DetailSafeHolder
public class DetailSafeHolder extends BaseHolder<AppInfo> implementsOnClickListener {@ViewInject(R.id.safe_layout)private RelativeLayout safe_layout;@ViewInject(R.id.safe_content)private LinearLayout safe_content;@ViewInject(R.id.safe_arrow)private ImageView safe_arrow;ImageView[] ivs;ImageView[] iv_des;TextView[] tv_des;LinearLayout[] des_layout;@Overridepublic View initView() {View view = UiUtils.inflate(R.layout.detail_safe);ViewUtils.inject(this, view);ivs = new ImageView[4]; // 初始化标题栏的图片ivs[0] = (ImageView) view.findViewById(R.id.iv_1);ivs[1] = (ImageView) view.findViewById(R.id.iv_2);ivs[2] = (ImageView) view.findViewById(R.id.iv_3);ivs[3] = (ImageView) view.findViewById(R.id.iv_4);iv_des = new ImageView[4]; // 初始化每个条目描述的图片iv_des[0] = (ImageView) view.findViewById(R.id.des_iv_1);iv_des[1] = (ImageView) view.findViewById(R.id.des_iv_2);iv_des[2] = (ImageView) view.findViewById(R.id.des_iv_3);iv_des[3] = (ImageView) view.findViewById(R.id.des_iv_4);tv_des = new TextView[4]; // 初始化每个条目描述的文本tv_des[0] = (TextView) view.findViewById(R.id.des_tv_1);tv_des[1] = (TextView) view.findViewById(R.id.des_tv_2);tv_des[2] = (TextView) view.findViewById(R.id.des_tv_3);tv_des[3] = (TextView) view.findViewById(R.id.des_tv_4);des_layout = new LinearLayout[4]; // 初始化条目线性布局des_layout[0] = (LinearLayout) view.findViewById(R.id.des_layout_1);des_layout[1] = (LinearLayout) view.findViewById(R.id.des_layout_2);des_layout[2] = (LinearLayout) view.findViewById(R.id.des_layout_3);des_layout[3] = (LinearLayout) view.findViewById(R.id.des_layout_4);LayoutParams layoutParams = safe_content.getLayoutParams();layoutParams.height=0;//默认为0safe_content.setLayoutParams(layoutParams);//必须经过上面这三步才能设置大小safe_arrow.setImageResource(R.drawable.arrow_down);return view;}@Overridepublic void refreshView(AppInfo data) {safe_layout.setOnClickListener(this);List<String> safeUrl = data.getSafeUrl();List<String> safeDesUrl = data.getSafeDesUrl();List<String> safeDes = data.getSafeDes();List<Integer> safeDesColor = data.getSafeDesColor(); // 0 1 2 3for (int i = 0; i < 4; i++) {if (i < safeUrl.size() && i < safeDesUrl.size()&& i < safeDes.size() && i < safeDesColor.size()) {ivs[i].setVisibility(View.VISIBLE);des_layout[i].setVisibility(View.VISIBLE);bitmapUtils.display(ivs[i], HttpHelper.URL + "image?name="+ safeUrl.get(i));bitmapUtils.display(iv_des[i], HttpHelper.URL + "image?name="+ safeDesUrl.get(i));tv_des[i].setText(safeDes.get(i));// 根据服务器数据显示不同的颜色,有可能文字颜色不一样int color;int colorType = safeDesColor.get(i);if (colorType >= 1 && colorType <= 3) {color = Color.rgb(255, 153, 0); // 00 00 00} else if (colorType == 4) {color = Color.rgb(0, 177, 62);} else {color = Color.rgb(122, 122, 122);}tv_des[i].setTextColor(color);} else {ivs[i].setVisibility(View.GONE);des_layout[i].setVisibility(View.GONE);}}}boolean flag=false;//默认不展开@Overridepublic void onClick(View v) {if (v.getId() == R.id.safe_layout) {int startHeight;int targetHeight;if (!flag) { // 展开的动画startHeight=0;targetHeight=getMeasureHeight();flag = true;//safe_content.setVisibility(View.VISIBLE);这样写也可以,不过显的特别突兀safe_content.getMeasuredHeight(); // 0} else {flag=false;//safe_content.setVisibility(View.GONE);startHeight=getMeasureHeight();targetHeight=0;}// 值动画ValueAnimator animator=ValueAnimator.ofInt(startHeight,targetHeight);final RelativeLayout.LayoutParams layoutParams = (android.widget.RelativeLayout.LayoutParams) safe_content.getLayoutParams();animator.addUpdateListener(new AnimatorUpdateListener() { // 监听值的变化@Overridepublic void onAnimationUpdate(ValueAnimator animator) {int value=(Integer) animator.getAnimatedValue();// 运行当前时间点的一个值layoutParams.height=value;safe_content.setLayoutParams(layoutParams);// 刷新界面System.out.println(value);}});animator.addListener(new AnimatorListener() { // 监听动画执行//当动画开始执行的时候调用@Overridepublic void onAnimationStart(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator arg0) {}@Overridepublic void onAnimationEnd(Animator arg0) {if(flag){safe_arrow.setImageResource(R.drawable.arrow_up);}else{safe_arrow.setImageResource(R.drawable.arrow_down);}}@Overridepublic void onAnimationCancel(Animator arg0) {}});animator.setDuration(500);animator.start();}}//onMeasure() 制定测量的规则// measure() 实际测量/*** 获取控件实际的高度*/public int getMeasureHeight(){int width = safe_content.getMeasuredWidth(); // 由于宽度不会发生变化 宽度的值取出来safe_content.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;// 让高度包裹内容,可以不写- //得先重新设置完规则再测量
// 参数1 测量控件mode 参数2 大小int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width); // mode+sizeint heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);// 我的高度 最大是1000// 测量规则 宽度是一个精确的值width, 高度最大是1000,以实际为准safe_content.measure(widthMeasureSpec, heightMeasureSpec); // 通过该方法重新测量控件return safe_content.getMeasuredHeight();}}
应用详情描述界面

DetailDesHolder :这个麻烦点,因为它默认是从7行的高度到包裹内容,所以得先计算出7行的高度
public class DetailDesHolder extends BaseHolder<AppInfo> implements OnClickListener {@ViewInject(R.id.des_content)private TextView des_content;@ViewInject(R.id.des_author)private TextView des_author;@ViewInject(R.id.des_arrow)private ImageView des_arrow;@ViewInject(R.id.des_layout)private RelativeLayout des_layout;@Overridepublic View initView() {View view=UiUtils.inflate(R.layout.detail_des);ViewUtils.inject(this, view);return view;}@Overridepublic void refreshView(AppInfo data) {des_content.setText(data.getDes());des_author.setText("作者:"+data.getAuthor());des_layout.setOnClickListener(this);//des_content 起始高度7行的高度LayoutParams layoutParams = des_content.getLayoutParams();layoutParams.height=getShortMeasureHeight();des_content.setLayoutParams(layoutParams);des_arrow.setImageResource(R.drawable.arrow_down);}/*** 获取7行的高度* @return*/public int getShortMeasureHeight(){// 复制一个新的TextView 用来测量,最好不要在之前的TextView测量 有可能影响其它代码执行TextView textView=new TextView(UiUtils.getContext());textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);//设置字体大小14dptextView.setMaxLines(7);textView.setLines(7);// 强制有7行int width=des_content.getMeasuredWidth(); // 开始宽度//得先重新设置完规则再测量int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width);int heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);textView.measure(widthMeasureSpec, heightMeasureSpec);return textView.getMeasuredHeight();}/*** 获取TextView 自己本身的高度* @return*/public int getLongMeasureHeight(){int width=des_content.getMeasuredWidth(); // 开始宽度des_content.getLayoutParams().height= ViewGroup.LayoutParams.WRAP_CONTENT;// 高度包裹内容int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width);int heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);des_content.measure(widthMeasureSpec,heightMeasureSpec);//return des_content.getMeasuredHeight();}boolean flag;// true展开了 false 没有展开,不写的话默认是false@Overridepublic void onClick(View v) {expand();}ScrollView scrollView;// scrollView.scrollTo(0, scrollView.getMeasuredHeight())/*** 获取到界面的ScollView,这样可以点箭头时就到了最后*/public ScrollView getScrollView(View view){ViewParent parent = view.getParent();if(parent instanceof ViewGroup){ViewGroup group=(ViewGroup) parent;if(group instanceof ScrollView){return (ScrollView)group;}else{return getScrollView(group);//用递归,知道获取到ScrollView}}else{return null;}}private void expand() {scrollView=getScrollView(des_layout);int startHeight;int targetHeight;if(!flag){flag=true;startHeight=getShortMeasureHeight();targetHeight=getLongMeasureHeight();}else{flag=false;startHeight=getLongMeasureHeight();targetHeight=getShortMeasureHeight();}final LayoutParams layoutParams = des_content.getLayoutParams();ValueAnimator animator=ValueAnimator.ofInt(startHeight,targetHeight);animator.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {int value=(Integer) animation.getAnimatedValue();layoutParams.height=value;des_content.setLayoutParams(layoutParams);scrollView.scrollTo(0, scrollView.getMeasuredHeight());// 让scrollView 移动到最下面}});animator.addListener(new AnimatorListener() { // 监听动画执行//当动画开始执行的时候调用@Overridepublic void onAnimationStart(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator arg0) {}@Overridepublic void onAnimationEnd(Animator arg0) {if(flag){des_arrow.setImageResource(R.drawable.arrow_up);}else{des_arrow.setImageResource(R.drawable.arrow_down);}}@Overridepublic void onAnimationCancel(Animator arg0) {}});animator.setDuration(500);//设置动画持续时间animator.start();}}
修改ListBaseAdapter,添加这个方法,每个应用界面、游戏界面就都能点listview了
@Overridepublic void onInnerItemClick(int position) {super.onInnerItemClick(position);Toast.makeText(UiUtils.getContext(), "position:"+position, 0).show();AppInfo appInfo = datas.get(position);Intent intent=new Intent(UiUtils.getContext(), DetailActivity.class);intent.putExtra("packageName", appInfo.getPackageName());UiUtils.startActivity(intent);}
UiUtils
/*** 可以打开activity* @param intent*/public static void startActivity(Intent intent) {// 如果不在activity里去打开activity 需要指定任务栈 需要设置标签if(BaseActivity.activity==null){intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);getContext().startActivity(intent);}else{BaseActivity.activity.startActivity(intent);}}
BaseActivity
public static BaseActivity activity;@Overrideprotected void onResume() {super.onResume();activity=this;}@Overrideprotected void onPause() {super.onPause();activity=null;}
附件列表


浙公网安备 33010602011771号