Android ListView项收缩效果

版权所有,禁止匿名转载;禁止商业使用。

项目中看到IOS上LIstView在显示隐藏一部分时有一个收缩的特效,但Android自带的没有。就想着能否自定义实现,下面是从项目中提取出来的Demo。


先上效果图:



点击每一行右边的图标显示隐藏;


一、自定义了ExpandableLayout是继承自LinearLayout:


package com.jerome.expand;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
public class ExpandableLayout extends LinearLayout {
  private String TAG = ExpandableLayout.class.getSimpleName();
  private int layoutHeight = -1;
  private int OPEN_LAYOUT_TIMES = 20;
  private int SLEEP_TIME = 15;
  private float layoutStep = 8;
  private OnExpandFinishListener onExpand = null;
  private OnCollapseFinishListener onCollapse = null;
  public interface OnExpandFinishListener {
    public void onExpandFinish();
  }
  public interface OnCollapseFinishListener {
    public void onCollapseFinish();
  }
  public void setOnExpandFinishListener(OnExpandFinishListener oeListener) {
    onExpand = oeListener;
  }
  public void setOnCollapseFinishListener(OnCollapseFinishListener ocListener) {
    onCollapse = ocListener;
  }
  public void setLayoutHeight(int height) {
    layoutHeight = height;
    layoutStep = 1.0f * layoutHeight / OPEN_LAYOUT_TIMES;
  }
  public ExpandableLayout(Context context) {
    super(context);
  }
  public ExpandableLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
  public void collapse() {
    new Thread() {
      public void run() {
        for (int i = 0; i < OPEN_LAYOUT_TIMES + 1; i++) {
          final int ii = i;
          post(new Thread() {
            public void run() {
              LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, (int) ((OPEN_LAYOUT_TIMES -ii) * layoutStep));
              setLayoutParams(params);
              if (ii == OPEN_LAYOUT_TIMES) {
                setVisibility(View.GONE);
                if(null!=onCollapse){
                  onCollapse.onCollapseFinish();
                }
              }
            }
          });
          try {
            Thread.sleep(SLEEP_TIME);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }.start();
  }
  public void expand() {
    if (layoutHeight <= 0) {
      return;
    }
    
    android.widget.LinearLayout.LayoutParams params = new android.widget.LinearLayout.LayoutParams(
        LayoutParams.MATCH_PARENT, 0);
    setLayoutParams(params);
    setVisibility(View.VISIBLE);
    
    new Thread() {
      public void run() {
        for (int i = 0; i < OPEN_LAYOUT_TIMES + 1; i++) {
          final int ii = i;
          post(new Thread() {
            public void run() {
              LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,(int) (ii * layoutStep));
              setLayoutParams(params);
              
              if (ii == OPEN_LAYOUT_TIMES) {
                if(null!=onExpand){
                  onExpand.onExpandFinish();
                }
              }
            }
          });
          
          try {
            Thread.sleep(SLEEP_TIME);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }.start();
  }
}

二、在Listview的Item配置文件中使用:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical" >
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
    <TextView
      android:id="@+id/list_item_text"
      android:layout_width="0dip"
      android:layout_height="wrap_content"
      android:layout_marginBottom="10dp"
      android:layout_marginLeft="10dp"
      android:layout_marginTop="10dp"
      android:layout_weight="1"
      android:paddingBottom="5dip"
      android:textColor="#FFFFFFFF"
      android:textSize="18dp" />
    <ImageView
      android:id="@+id/list_item_more"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center_vertical"
      android:paddingLeft="10dip"
      android:src="@drawable/indicate_more_oper_icon_pressed" />
  </LinearLayout>
  <com.jerome.expand.ExpandableLayout
    android:id="@+id/list_item_more_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ff303537"
    android:orientation="horizontal"
    android:paddingBottom="15dip"
    android:paddingTop="15dip"
    android:visibility="gone" >
    <LinearLayout
      android:layout_width="0dip"
      android:layout_height="wrap_content"
      android:layout_gravity="center_vertical"
      android:layout_weight="1"
      android:gravity="center"
      android:orientation="horizontal" >
      <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_music_not_collect" />
      <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dip"
        android:text="收藏"
        android:textColor="#FFFFFFFF"
        android:textSize="14sp" />
    </LinearLayout>
    <LinearLayout
      android:layout_width="0dip"
      android:layout_height="wrap_content"
      android:layout_gravity="center_vertical"
      android:layout_weight="1"
      android:gravity="center"
      android:orientation="horizontal" >
      <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_music_delete" />
      <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dip"
        android:gravity="center_horizontal"
        android:text="删除"
        android:textColor="#FFFFFFFF"
        android:textSize="14sp" />
    </LinearLayout>
  </com.jerome.expand.ExpandableLayout>
</LinearLayout>

三、在代码中使用:


class MyAdapter extends BaseAdapter {
    List<String> data = new ArrayList<String>();
    MyAdapter() {
      initData();
    }
    private void initData() {
      for (int i = 0; i < 30; i++) {
        data.add("第" + i + "行");
      }
    }
    @Override
    public int getCount() {
      return data.size();
    }
    @Override
    public Object getItem(int position) {
      return data.get(position);
    }
    @Override
    public long getItemId(int position) {
      return 0;
    }
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
      final HolderView holder;
      if (convertView == null) {
        holder = new HolderView();
        convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.list_item, null);
        holder.text = (TextView)convertView.findViewById(R.id.list_item_text);
        holder.more = (ImageView)convertView.findViewById(R.id.list_item_more);
        holder.moreLayout = (ExpandableLayout)convertView.findViewById(R.id.list_item_more_layout);
        convertView.setTag(holder);
      } else {
        holder = (HolderView)convertView.getTag();
      }
      holder.more.setOnClickListener(new OnClickListener(){
        @Override
        public void onClick(View v) {
          int visable = holder.moreLayout.getVisibility();
          if (visable == View.VISIBLE) {
            holder.moreLayout.setLayoutHeight(150);
            holder.moreLayout.setOnCollapseFinishListener(new OnCollapseFinishListener(){
              @Override
              public void onCollapseFinish() {
                selectedPosition = -1;
              }
              
            });
            holder.moreLayout.collapse();
          } else {
            holder.moreLayout.setLayoutHeight(150);
            holder.moreLayout.expand();
            selectedPosition = position;
notifyDataSetChanged();
          }
        }
        
      });
      if (selectedPosition == position) {
        holder.moreLayout.setVisibility(View.VISIBLE);
      } else {
        holder.moreLayout.setVisibility(View.GONE);
      }
      holder.text.setText(data.get(position));
      return convertView;
    }
  }


0 0