Android常用开源项目(二十)
Android开发之ListView点击展开和收缩的实现
手机屏幕由于空间的限制,所以优先显示主要的信息在手机 屏幕上面,而要隐藏次要的信息。这样才能给用户展现出简洁的界面。而且显示信息一般都是以列表的形式展现,所以我们首先会考虑到使用List View来展示数据,如果没点击一个item就跳转到另外一个页面,然后在点击返回键返回,这样的用户体验就非常差。此刻,好的App交互设计师首先考虑的就是点击List View的Item来隐藏和展开数据显示。这不是新的控件,只是在原有的item上增加了隐藏和展示的动画效果,是用户体验较好。
具体的实现步骤如下:
-
自定义动画(隐藏和展示的动画)
-
在ListView的item布局文件中把要隐藏的内容专门用RelativeLayout或者LinearLayout包裹起来
-
在Adapter中把动画效果增加其中
代码如下:
-
自定义动画效果的代码
public class ViewExpandAnimation extends Animation {
private View mAnimationView = null;
private LayoutParams mViewLayoutParams = null;
private int mStart = 0;
private int mEnd = 0;
public ViewExpandAnimation(View view){
animationSettings(view, 500);
}
public ViewExpandAnimation(View view, int duration){
animationSettings(view, duration);
}
private void animationSettings(View view, int duration){
setDuration(duration);
mAnimationView = view;
mViewLayoutParams = (LayoutParams) view.getLayoutParams();
mStart = mViewLayoutParams.bottomMargin;
mEnd = (mStart == 0 ? (0 - view.getHeight()) : 0);
view.setVisibility(View.VISIBLE);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if(interpolatedTime < 1.0f){
mViewLayoutParams.bottomMargin = mStart + (int) ((mEnd - mStart) * interpolatedTime);
// invalidate
mAnimationView.requestLayout();
}else{
mViewLayoutParams.bottomMargin = mEnd;
mAnimationView.requestLayout();
if(mEnd != 0){
mAnimationView.setVisibility(View.GONE);
}
}
}
}
2.ListView的item的布局文件(考虑到布局文件的代码量,以图片的形式给出)
List View的item布局文件
3.自定义的Adapter实现
public class CustomListAdapter extends BaseAdapter{
private LayoutInflater mInflater;
public CustomListAdapter(Context context){
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int arg0) {
return mList.get(arg0);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(getCount() == 0){
return null;
}
ViewHolder holder = null;
if(convertView == null){
convertView = mInflater.inflate(R.layout.expand_item, null);
holder = new ViewHolder();
holder.ivImage = (ImageView) convertView.findViewById(R.id.ivIcon);
holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
holder.tvVer = (TextView) convertView.findViewById(R.id.tvVer);
holder.tvSize = (TextView) convertView.findViewById(R.id.tvSize);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
AppInfo ai = mList.get(position);
holder.ivImage.setImageBitmap(ai.appIcon);
holder.tvName.setText(ai.appName);
holder.tvVer.setText(ai.appVer);
holder.tvSize.setText(ai.appSize);
// resize the button width and margin
int btnWidth = (int) ((mLcdWidth - 20 - 10 * mDensity) / 3);
RelativeLayout.LayoutParams lp = null;
Button btnOpen = (Button) convertView.findViewById(R.id.btnOpen);
lp = (RelativeLayout.LayoutParams) btnOpen.getLayoutParams();
lp.width = btnWidth;
btnOpen.setLayoutParams(lp);
btnOpen.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "打开应用!", Toast.LENGTH_SHORT).show();
}
});
Button btnView = (Button) convertView.findViewById(R.id.btnView);
lp = (RelativeLayout.LayoutParams) btnView.getLayoutParams();
lp.width = btnWidth;
lp.leftMargin = 10;
btnView.setLayoutParams(lp);
btnView.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "查看详情!", Toast.LENGTH_SHORT).show();
}
});
Button btnWarning = (Button) convertView.findViewById(R.id.btnWarning);
lp = (RelativeLayout.LayoutParams) btnWarning.getLayoutParams();
lp.width = btnWidth;
lp.leftMargin = 10;
btnWarning.setLayoutParams(lp);
btnWarning.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "举报应用!", Toast.LENGTH_SHORT).show();
}
});
// get footer height
RelativeLayout footer = (RelativeLayout) convertView.findViewById(R.id.footer);
int widthSpec = MeasureSpec.makeMeasureSpec((int) (mLcdWidth - 10 * mDensity), MeasureSpec.EXACTLY);
footer.measure(widthSpec, 0);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) footer.getLayoutParams();
params.bottomMargin = -footer.getMeasuredHeight();
footer.setVisibility(View.GONE);
return convertView;
}
}
对隐藏和展示的布局不分进行测量控制
4.在ListView的OnItemClickListener方法中实现动画效果
ListView的OnItemClickListener实现动画效果
5.展示效果
List View展示数据
ListView显示隐藏的数据