ListView使用方法大总结
2016-09-07 13:08
363 查看
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的内部,并且将布局中的控件作为成员变量。
设置项目分割线:
实现具有弹性的ListView(下拉到最下面或者上拉到最上边ListView可以继续滑行一段距离)
首先定义一个ListView:
这里还在ListView的构造方法中做了一个处理,主要就是为了适配各种像素密度的屏幕,具有更好的兼容性。
实现ToolBar自动隐藏的ListView:
这里我们会使用到ToolBar,所以我们先定义一个ToolBar:
实现对话框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>
下面贴出主程序
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();//通知界面进行更新
}
});
}
下面是实验结果:
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();//通知界面进行更新
}
});
}
下面是实验结果:
相关文章推荐
- RecyclerView 使用方法总结(一):RecyclerView的基本用法,及实现ListView
- ListView的使用方法总结
- Listview控件使用SimpleAdapter适配器实现屏幕下滑增加一个item选项以及用到的方法总结
- ExpandableListView使用重要方法总结
- ListView 使用方法简单总结
- solaris磁带设备使用方法总结
- 网站皮肤的使用方法总结
- Google中site:的使用方法总结
- 使用VMWare+SoftICE的方法总结
- Mcad学习笔记之异步编程(AsyncCallback委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)
- ASP连接数据库的11种方法——本文总结了使用ASP链接各种数据库的方法
- MySQL中的字符集涵义及使用方法总结(二)
- extern使用方法总结!
- 各种数据库的连接串(总结DSN的使用方法)
- 内表使用方法总结之二----常用方法
- Log4j使用方法总结
- Google中site:的使用方法总结
- 总结:ADO.NET在开发中的部分使用方法和技巧 (转贴)
- Google中site:的使用方法总结
- Mcad学习笔记之异步编程(AsyncCallback委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)