ListView
定义:
- ListView是显示垂直可滚动的列表项视图,列表项的来源可以使用一个适配Adapter,Adapter可将内容从源(如数组或数据库)转换成视图放在列表中。
- ListView 控件可使用四种不同视图显示项目。通过此控件,可将项目组成带有或不带有列标头的列,并显示伴随的图标和文本。 可使用 ListView 控件将称作 ListItem 对象的列表条目组织成下列四种不同的视图之一:1.大(标准)图标 2.小图标 3.列表 4.报表
- 而View属性决定在列表中控件使用何种视图显示项目。还可用 LabelWrap 属性控制列表中与项目关联的标签是否可换行显示。另外,还可管理列表中项目的排序方法和选定项目的外观。
还是不懂什么是ListView?那就上图(直观点):
ListView中一些常用的XML属性:
简单的ListView使用:
- 一个ListView通常有两个职责。
- 将数据填充到布局。
- 处理用户的选择点击等操作
- 一个ListView的创建需要3个元素。
- ListView中的每一列的View。
- 填入View的数据或者图片等。
- 连接数据与ListView的适配器。
ListView视图
在Layout布局activity_main里面加入一个ListView
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
在activity活动MainActivity中把这个ListView实例化,以便之后操作。
将ListView mlistView = (ListView) findViewById(R.id.list_view);写在onCreate()方法里面就可以了,如下所示
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView mlistView = (ListView) findViewById(R.id.list_view);
}
效果:
但是这里面空空如也,那是因为我们还没有往里面放item。
Item视图
从最简单开始,我们就做一个只显示一行文字的Item,非常简单,我们只要在layout目录下新建一个xml就可以,在这里我们将它命名为list_item.xml,然后往里面放一个TextView
- 注意:xml中只能放一个TextView,LinearLayout不要
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="20dp"/>
现在我们Item的布局也有了,但是我们现在还存在两个问题 - 1.我们虽说有了Item,但是!Item里面还是没有内容啊! - 2.我们有了ListView布局又有了Item布局,但怎么把它们连在一起呢?
我们一个一个解决,先把内容给写好,所以接下来我们写Data中的数据
Data数据
这里就用一个最简单字符串数组来储存数据
为了简便我们就把它直接写在MainActivity中
private String[] data = {
"item_1",
"item_2",
"item_3",
"item_4",
"item_5",
"item_6",
"item_7"
};
终于我们ListView的布局啊,Item的布局啊,数据啊都写好了!
我们只要把它们给连接起来就好了,但是怎么办呢?
这里我们就要引入一个适配器(Adapter)
Adapter适配器
适配器是一个连接数据和AdapterView(ListView就是一个典型的AdapterView,后面还会学习其他的)的桥梁,通过它能有效地实现数据与AdapterView的分离设置,使AdapterView与数据的绑定更加简便,修改更加方便
其实适配器还有很多,要注意的是,各种Adapter只不过是转换的方式和能力不一样而已。
在这里我们就用一个最简单的ArrayAdapter,因为我们只显示一行字符串
所以将ArrayAdapter的泛型指定为String,也就是ArrayAdapter< String >
不废话了,赶快用代码绑定看看吧,同样也是在MainActivity中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView mlistView = (ListView) findViewById(R.id.list_view);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,R.layout.list_item,data);
mlistView.setAdapter(adapter);
}
注意:我们看到Adapter那行,传了三个参数,分别是上下文,Item的布局文件,数据。
运行结果:
一个非常简单的ListView的运用程序就实现啦!那下面我们就考虑下它的优化:
ListView的优化
- ListView的优化主要包括两个方面,分别是对自身的优化以及其适配器(Adapter)的优化。
- 现在ListView有点落后于时代了,用的比较多的是RecyclerView。(或许以后有空会写一份关于它的博客)
ListView自身的优化
- UNSPECIFIED:未指定的,父类不对子类施加任何限制。
- EXACTLY:确定的,父类确定其子类控件的大小。
- AT_MOST:最大值,需要子类去测量自身大小确定。如果我们设置宽高为wrap_content,即AT_MOST,表示其宽高有控件本身去测量确定,而如果是match_parent,则EXACTLY,表示确定的大小。
Adapter优化。
对于Adapter的优化,主要包括以下几个步骤:
复用convertView,减少子布局的生成。
定义ViewHolder,减少findViewById()的次数。
ListView参考资料:https://blog.csdn.net/pibalibala/article/details/44515225
ViewPager
定义:
ViewPager是Android开发者比较常用的一个控件了,由于它允许数据页从左到右或者从右到左翻页,因此这种交互也备受设计师的青睐。在APP中的很多场景都用得到,比如第一次安装APP时的用户引导页、图片浏览时左右翻页、广告Banner页等等都会用到ViewPager
1.ViewPager的简介和作用
ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view
1)ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类。
2)ViewPager类需要一个PagerAdapter适配器类给它提供数据。
3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。
2.ViewPager的适配器
简介中提到了PagerAdapter,和ListView等控件使用一样,需要ViewPager设置PagerAdapter来完成页面和数据的绑定,这个PagerAdapter是一个基类适配器,我们经常用它来实现app引导图,它的子类有FragmentPagerAdapter和FragmentStatePagerAdapter,这两个子类适配器用于和Fragment一起使用,在安卓应用中它们就像listview一样出现的频繁。
public class AdapterViewpager extends PagerAdapter {
private List<View> mViewList;
public AdapterViewpager(List<View> mViewList) {
this.mViewList = mViewList;
}
@Override public int getCount() {//必须实现
return mViewList.size();
}
@Override public boolean isViewFromObject(View view, Object object) {//必须实现
return view == object;
}
@Override public Object instantiateItem(ViewGroup container, int position) {//必须实现,实例化
container.addView(mViewList.get(position));
return mViewList.get(position);
}
@Override public void destroyItem(ViewGroup container, int position, Object object) {//必须实现,销毁
container.removeView(mViewList.get(position));
}
}
//链接:https://www.jianshu.com/p/e5abbda4a71c
简单的ViewPager使用:
1. xml引用
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
2. page布局
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="@+id/tv"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FAE8DA"
android:gravity="center"
android:text="Hello"
android:textSize="22sp">
</TextView>
3. 创建适配器
可直接创建PagerAdapter,亦可创建它的子类
public class MyPagerAdapter extends PagerAdapter {
private Context mContext;
private List<String> mData;
public MyPagerAdapter(Context context ,List<String> list) {
mContext = context;
mData = list;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = View.inflate(mContext, R.layout.item_base,null);
TextView tv = (TextView) view.findViewById(R.id.tv);
tv.setText(mData.get(position));
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container,position,object); 这一句要删除,否则报错
container.removeView((View)object);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
4. 设置适配器
private void setVp() {
List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("第"+i+"个View");
}
ViewPager vp = (ViewPager) findViewById(R.id.vp);
vp.setAdapter(new MyPagerAdapter(this,list));
}
效果:
与Fragment结合使用
这种方法最好用于有限个静态fragment页面的管理。尽管不可见的视图有时会被销毁,但用户所有访问过的fragment都会被保存在内存中。因此fragment实例会保存大量的各种状态,这就造成了很大的内存开销。
与Fragment结合使用其实也一样,只是用Fragment代替原先的View,填充Viewpager;然后就是Adapter不一样,配合Fragment使用的有两个Adapter:FragmentPagerAdapter和FragmentStatePagerAdapter。
相同点:
FragmentPagerAdapter和FragmentStatePagerAdapter都继承自PagerAdapter
不同点:
卸载不再需fragment时,各自采用的处理方法有所不同
FragmentStatePagerAdapter会销毁不需要的fragment。事务提交后, activity的FragmentManager中的fragment会被彻底移除。 FragmentStatePagerAdapter类名中的“state”表明:在销毁fragment时,可在onSaveInstanceState(Bundle)方法中保存fragment的Bundle信息。用户切换回来时,保存的实例状态可用来恢复生成新的fragment
FragmentPagerAdapter有不同的做法。对于不再需要的fragment, FragmentPagerAdapter会选择调用事务的detach(Fragment)方法来处理它,而非remove(Fragment)方法。也就是说, FragmentPagerAdapter只是销毁了fragment的视图, fragment实例还保留在FragmentManager中。因此,FragmentPagerAdapter创建的fragment永远不会被销毁
也就是:在destroyItem()方法中,FragmentStatePagerAdapter调用的是remove()方法,适用于页面较多的情况;FragmentPagerAdapter调用的是detach()方法,适用于页面较少的情况。但是有页面数据需要刷新的情况,不管是页面少还是多,还是要用FragmentStatePagerAdapter,否则页面会因为没有重建得不到刷新
ViewPage参考:
https://blog.csdn.net/weixin_39251617/article/details/79399592
https://www.jianshu.com/p/e5abbda4a71c
基于ViewPager实现广告轮播控件 //此项技能还是挺有用的
https://github.com/daimajia/AndroidImageSlider //转载