ListView使用方法大总结

Adapter一般有以下的几种实现类:ArrayAdapter,SimpleAdapter,SimpleCursorAdapter,BaseAdapter。

ArrayAdapter的每一个列表只能是一个TextView,ArrayAdapter的使用方法如下:

ArrayAdapter adapter=new ArrayAdapter(Context,一个TextView布局,String 数组);

SimpleAdapter常常用来实现

这种的界面。

使用和方法如下:

SimpleAdapter simpleAdapter=new SimpleAdapter(Context,一个List<?extends Map<String,?>>类型的集合对象,布局,String[]类型的参数,数组里边存放Map里边的键值,int[]类型的参数,数组里边存放item中每一个组件的id号)

下面来介绍以下BaseAdapter的使用技巧:

1.使用ViewHolder

viewHolder一般定义在Adapter的内部,并且将布局中的控件作为成员变量。

public class ViewHolderAdapter extends BaseAdapter {
    private List<String> mData;
    private LayoutInflater mInflater;
    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder=null;
        if (convertView==null){
            holder=new ViewHolder();
            convertView=mInflater.inflate(R.layout.viewholder_item,null);
            holder.img= (ImageView) convertView.findViewById(R.id.imageview);
            holder.title= (TextView) convertView.findViewById(R.id.textview);
            convertView.setTag(holder);
        }
        else{
            holder= (ViewHolder) convertView.getTag();
        }
        holder.img.setBackgroundResource(R.drawable.ic_launcher);
        holder.title.setText(mData.get(position));
        return convertView;
    }

    public ViewHolderAdapter(List<String> mData, Context context) {
        this.mData = mData;
        mInflater=LayoutInflater.from(context);
    }
    <span style="color:#FF0000;">public  final class ViewHolder{
        public ImageView img;
        public TextView title;
    }
</span>}
public class MainActivity extends AppCompatActivity {

    private ListView myList;
    private ArrayList<String> mData=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myList= (ListView) findViewById(R.id.myList);
        for(int i=0;i<50;i++){
            mData.add("item"+i);
        }
        ViewHolderAdapter myHolderAdapter=new ViewHolderAdapter(mData,this);
        myList.setAdapter(myHolderAdapter);
        //动态添加ListView
        mData.add("新的一项");
        myHolderAdapter.notifyDataSetChanged();
        myList.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                switch(scrollState){
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                        //滑动停止的时候
                        Log.d("TEST","SCROLL_STATE_IDLE");
                        break;
                    case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                        //正在滚动
                        Log.d("TEST","SCROLL_STATE_TOUCH_SCROLL");
                        break;
                    case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                        //手指抛开以后,Listview依靠惯性滑动的时候会回调这个方法
                        Log.d("TEST","SCROLL_STATE_FLING");
                        break;
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    //滚动的时候会一直调用
                    Log.d("TEST","正在滚动");
            }
        });
    }
}


以下是ListView的一些设置:

设置项目分割线:

android:divider="@android:color/darker_gray"
android:dividerHeight="10dp"
隐藏ListView的滚动条;

android:scrollbars="none"
设置ListView的Item点击效果:

android:listSelector="RGB值"
设置ListView显示在第几页:

listView.setSelection(N);
listview平滑显示:

mListView.smoothScro;lBy(distance,duiration);
mListView.smoothScrollByoffset(offset);
mListView.smoothScrollToPosition(index);


实现具有弹性的ListView(下拉到最下面或者上拉到最上边ListView可以继续滑行一段距离)

首先定义一个ListView:

public class MyListView extends ListView{

     private  int mMaxOvewDistance=100;
    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        DisplayMetrics metrics=context.getResources().getDisplayMetrics();
        float  density=metrics.density;
        mMaxOvewDistance=(int) (density*mMaxOvewDistance);
    }

    public MyListView(Context context) {
        super(context);
    }

    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    <span style="color:#FF0000;">@Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {

        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,<span style="color:#3333FF;">mMaxOvewDistance</span>, isTouchEvent);
    }</span>


}
重写overScrollBy这个方法,上边蓝色的部分的参数表示可以沿着Y轴滑动的距离。

这里还在ListView的构造方法中做了一个处理,主要就是为了适配各种像素密度的屏幕,具有更好的兼容性。


实现ToolBar自动隐藏的ListView:

这里我们会使用到ToolBar,所以我们先定义一个ToolBar:

 <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/toolbar"
        android:background="@color/colorAccent">

    </android.support.v7.widget.Toolbar>
下面贴出主程序:
public class MainActivity extends AppCompatActivity {
    private int scaledTouchSlop;
    private float firstY = 0;
    private Toolbar toolbar;
    private ObjectAnimator animtor;
    private ListView myList;
    private ArrayList<String> mData=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myList= (ListView) findViewById(R.id.myList);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        for(int i=0;i<50;i++){
            mData.add("item"+i);
        }
        ViewHolderAdapter myHolderAdapter=new ViewHolderAdapter(mData,this);
        initHeadView();//初始化
        myList.setAdapter(myHolderAdapter);
        scaledTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();//滑动的最小距离
        myList.setOnTouchListener(new View.OnTouchListener() {
            private float currentY;
            private int direction;
            private boolean mShow = true;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch(event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        firstY=event.getY();
                        break;
                    case  MotionEvent.ACTION_MOVE:
                          currentY=event.getY();
                          if ((currentY-firstY)>scaledTouchSlop){
                              direction=0;
                          }else if((firstY-currentY)>scaledTouchSlop){
                              direction=1;

                          }
                         if(direction==1){
                             if (mShow){
                                 toolbarAnim(1);
                                 mShow=!mShow;
                             }
                         }
                        else if (direction==0){
                                toolbarAnim(0);
                                mShow=!mShow;
                         }
                        break;
                }
                return false;
            }
        });
    }
    public void initHeadView(){
        View view = new View(this);
        AbsListView.LayoutParams params = new AbsListView.LayoutParams
                (AbsListView.LayoutParams.MATCH_PARENT,
                        (int)getResources().getDimension(R.dimen.abc_action_bar_default_height_material));
        view.setLayoutParams(params);
        myList.addHeaderView(view);

    }
    public void toolbarAnim(int direction){
        //开始新的动画之前要先取消以前的动画
        if(animtor!=null&&animtor.isRunning()){
            animtor.cancel();
        }
        if(direction == 0){//手指向下滑动,显示ToolBar
            //toolbar.getTranslationY()获取的是Toolbar距离自己顶部的距离
            animtor = ObjectAnimator.ofFloat(toolbar, "translationY", toolbar.getTranslationY(), 0);
        }else if( direction == 1){
            animtor = ObjectAnimator.ofFloat(toolbar, "translationY", toolbar.getTranslationY(), -toolbar.getHeight());
    }
        animtor.start();
    }
}
这里讲一下ofFoat方法中几个参数的意义:

ofFloat()方法的第一个参数表示动画操作的对象(可以是任意对象)第二个参数表示操作对象的属性名字(只要是对象有的属性都可以)第三个参数之后就是动画过渡值。当然过度值可以有一个到N个,如果是一个值的话默认这个值是动画过渡值的结束值。如果有N个值,动画就在这N个值之间过渡。

实现对话框ListView:

首先我们需要写两个对话框的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:gravity="left"
    android:padding="10dp">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/icon_in"
        android:src="@drawable/ic_launcher"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text_in"
        android:background="@drawable/chatitem_out_bg"
        android:layout_marginLeft="10dp"
        android:gravity="center"
        android:textSize="16sp"/>

</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="10dp"
    android:gravity="right">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text_out"
        android:background="@drawable/chatitem_in_bg"
        android:gravity="center"
        android:layout_marginRight="10dp"
        android:textSize="16sp"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/icon_out"
        android:src="@drawable/ic_launcher"/>
</LinearLayout>
然后实现完成BaseAdapter,在getView中进行布局类型的判断

下面贴出主程序

private ListView mListView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView= (ListView) findViewById(R.id.mylistview);
        mListView.setDivider(null);//去除下划线
        ChatItemListViewBean bean1=new ChatItemListViewBean();
        bean1.setType(0);
        bean1.setIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher));
        bean1.setText("啊啊啊");
        ChatItemListViewBean bean2=new ChatItemListViewBean();
        bean2.setType(1);
        bean2.setIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher));
        bean2.setText("好好好");
        List<ChatItemListViewBean> data=new ArrayList<ChatItemListViewBean>();
        data.add(bean1);
        data.add(bean2);
        mListView.setAdapter(new ChatItemListViewAdapter(data,this));
    }
显示效果:

这里需要注意getItemViewType和getViewTypeCount这两个函数,getViewTypeCount这个方法告诉ListView我共有多少种item,getItemViewType方法告诉ListView每行该显示哪种item,并且该方法中返回的type类型必须为整数且不能大于getViewTypeCount返回的数。

动态改变ListView的布局:

当点击了Item时,其布局文件发生改变来达到一个Focus的效果。一般有两种方法。一种是将两种布局文件写在一起,通过控制布局的显示。隐藏,来达到切换布局的效果;另一种则是在getView()的时候,通过判断来选择加载不同的布局,这样就要在每次点击操作后刷新布局,重写调用getView(),使用notifyDataSetChanged()方法来实现。

这里选择后面一种方法来实现动态改变ListView的布局。

首先还是实现Adapter下面贴出代码:

Adapter中有两个重要的方法,addFocusView和addNormalView,前者只是加载一个ImageView,后者要加载另外一个布局,这个布局包括一个ImageView,一个TextView,然后在getview这个函数中进行判断,如果哪个Item被点击了,就把当前的这一栏改成FocusView。当然getview只能在初始化的时候进行调用,我们在MainActivity中对ITem设置监听,在listview被点击的时候,调用notifyDataSetChanged()方法来实现数据刷新的功能。

public class dymicAdapter extends BaseAdapter{
    private List<String> mData;
    private Context mContext;
    private int mCurrentItem=0;//<span style="font-size:10px;">默认是第一个Item</span>
    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LinearLayout layout=new LinearLayout(mContext);
        layout.setOrientation(LinearLayout.VERTICAL);
        if(mCurrentItem==position){
            layout.addView(addFocusView(position));

        }
        else{
            layout.addView(addNormalView(position));
        }
        return layout;
    }

    public void setCurrentItem(int currentItem) {
        this.mCurrentItem = currentItem;
    }
    public dymicAdapter(List<String> mData, Context mContext) {
        this.mData = mData;
        this.mContext = mContext;
    }
    private View addFocusView(int i){
        ImageView iv=new ImageView(mContext);
        iv.setImageResource(R.drawable.ic_launcher);
        return iv;
    }
    private View addNormalView(int i){
        LinearLayout layout=new LinearLayout(mContext);
        layout.setOrientation(LinearLayout.HORIZONTAL);
        ImageView iv=new ImageView(mContext);
        iv.setImageResource(R.drawable.in_icon);
        layout.addView(iv,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
        TextView tv=new TextView(mContext);
        tv.setText(mData.get(i));
        layout.addView(tv,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
        layout.setGravity(Gravity.CENTER);
        return layout;
    }
}
下面是MainActivity的主程序:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView myListView= (ListView) findViewById(R.id.mylistview);
        List<String> data=new ArrayList<String>();
        for(int i=0;i<50;i++){
            data.add("Item"+i);
        }
        final dymicAdapter myadapter=new dymicAdapter(data,this);
        myListView.setAdapter(myadapter);
        myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                myadapter.setCurrentItem(position);
                myadapter.notifyDataSetChanged();//通知界面进行更新

            }
        });
    }

下面是实验结果:



阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭