自定义ListView实现底部动画更新item

来源:互联网 发布:前海开源人工智能基金 编辑:程序博客网 时间:2024/05/29 15:02

1. 源代码 

实现思想:理解ListView加载items的原理:ListView永远仅仅只是使用第一次刚好可以显示一屏幕数量的items,向下拉而可见的items都是在复用前面第一次显示一屏幕的items而已;而且在适配器(继承BaseAdapter)的getView()中获得item时,每次下拉都会对所有可见的items调用getView()方法,但是这里仅仅只是要求最后更新的item做下拉动画,所有必须通过记录当前更新的item的position(索引),然后在getView()中根据该记录的position来调用动画;在getView()时候,item还没有初始化时,应设置动画。

package com.example.scrollviewdemo;import java.util.LinkedList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.animation.AnimationSet;import android.view.animation.AnimationUtils;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;public class MainActivity extends Activity {    private ListView mListView;    private List<String> mDataList = new LinkedList<String>();    private MyAdapater mAdapter = null;    /**     * 重点:记录ListView中当前正在更新的位置,初始值为是为-1表示开始没有要动画加载的item     */    private int mCurrentPosition = -1;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                for (int i = 0; i < 5; ++i) {            mDataList.add("Habby and Marry");        }                mListView = (ListView) findViewById(R.id.list);        mAdapter = new MyAdapater();        /**         * 此处设置时,则会第一次更新ListView的items(调用Adapter的getView()等函数),         * 这时,如果是超过了一屏幕,则只显示一屏的items。如果向下拉,系统就会重用         * 上面出去屏幕的item。         */        mListView.setAdapter(mAdapter);                mListView.setOnScrollListener(new OnScrollListener() {            private boolean isBottom = false;                        @Override            public void onScrollStateChanged(AbsListView view, int scrollState) {                if (scrollState == SCROLL_STATE_IDLE && isBottom) {// 底部                    mDataList.add("我们结婚吧!");                    mCurrentPosition = mDataList.size() - 1; // 记录当前更新数据的position                    mAdapter.notifyDataSetChanged();                }            }            @Override            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {                if (firstVisibleItem + visibleItemCount == totalItemCount) { // 滚到了底部                    isBottom = true;                } else {                    isBottom = false;                }            }        });    }    private class MyAdapater extends BaseAdapter {        @Override        public int getCount() {            return mDataList.size();        }        @Override        public Object getItem(int position) {            return mDataList.get(position);        }        @Override        public long getItemId(int position) {            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            ViewHolder mViewHolder = null;            /**             * getView()和ListView工作的原理是:当回收站里的item们来自于getView()的(convertView == null             * 表示不能从回收站里获得,必须自己创建)的时候,这些item都是新建立的,然后等到可以滑动,并且有             * 滑动隐藏掉的item时候,就把隐藏掉的item从ListView中去除,然后原封不动(不改变任何状态)的保存             * 在回收站里;当(getView != null)的时候,也就是说可以从回收站里获得item了。这就是item复用。             */            if (convertView == null) { // 回收站里没有现成的item可用                convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.chat_item_2, null);                mViewHolder = new ViewHolder();                mViewHolder.mTextView = (TextView) convertView.findViewById(R.id.text);                convertView.setTag(mViewHolder);                mViewHolder.animSet = (AnimationSet) AnimationUtils.loadAnimation(MainActivity.this, R.anim.translate1);                convertView.startAnimation(mViewHolder.animSet);            } else {                mViewHolder = (ViewHolder) convertView.getTag();            }            mViewHolder.mTextView.setText(mDataList.get(position));            /**             * 这里是因为,手指滑动ListView或notifyDataSetChanged()方法都会重画所以可见的item,这里仅仅是需要             * 对当前更新的(增加的)item做动画,其他的item不做动画。             */            if (mCurrentPosition == position) {                convertView.startAnimation(mViewHolder.animSet);            }            return convertView;        }    }    private class ViewHolder {        private TextView mTextView;        private AnimationSet animSet; // item动画    }}

2. 动画的xml(R.anim.translate1)是:

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"    android:interpolator="@android:anim/decelerate_interpolator"    android:duration="400" >        <translate         android:fromYDelta="100%"         android:toYDelta="0"         android:duration="400"/>            <alpha         android:fromAlpha="0.0"         android:toAlpha="1.0"        android:duration="300" /></set>


3. main.xml是:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:background="@android:color/darker_gray" >       <ListView        android:id="@+id/list"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:scrollbars="vertical"        android:divider="@android:color/darker_gray"        android:dividerHeight="16dip"        android:fadingEdge="vertical" /></LinearLayout>


4. chat_item_2.xml

<?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:gravity="center_horizontal"    android:orientation="vertical"    android:background="@android:color/transparent" >    <RelativeLayout        android:layout_width="fill_parent"        android:layout_height="150dip"        android:background="@android:color/white"        android:layout_gravity="center_vertical"        android:gravity="center_vertical"        android:paddingLeft="12dip"        android:paddingRight="12dip" >        <ImageView            android:id="@+id/iv_chat_item_2"            android:layout_width="60dp"            android:layout_height="60dp"            android:layout_alignParentRight="true"            android:contentDescription="@android:string/defaultMsisdnAlphaTag"            android:src="@drawable/boy" />        <TextView            android:id="@+id/text"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="50dp"            android:layout_toLeftOf="@+id/iv_chat_item_2"            android:background="@drawable/msg_sendto_done_bg_nor"            android:text=""            android:textColor="@color/grey21" />    </RelativeLayout></LinearLayout>

另外:对ListView加载item的理解很重要,只有理解了ListView的原理,才能写出更加好的ListView,这里有几个链接说得很好:

http://mzh3344258.blog.51cto.com/1823534/889879

http://www.cnblogs.com/lucifinilsu/p/3441787.html

http://www.cnblogs.com/lucifinilsu/p/3436769.html

0 0
原创粉丝点击