安卓Adapte适配器
Adapter是用来帮助填充数据的中间桥梁,简单点说就是:将各种数据以合适的形式显示到view上,提供 给用户看!
ListView
View:所有可视化控件的父类
(一般用不到)
ListView的一般步骤
使用ArrayAdapter实现文字列表
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
ArrayAdapter一种适配器,ArrayAdapter有多个构造函数的重载,这里选择string,然后依次传入当前上下文、listview子项布局的id, 这里android.R.layout.simple_list_item_1作为ListView子项布局的id,最后调用setAdapter()方法,将构建好的适配器对象传递出去
public class MainActivity extends AppCompatActivity {
private String[] data = {"Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango",
"Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
MainActivity.this, android.R.layout.simple_list_item_1, data);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
}
定制ListView的界面
整体思路
首先新建Fruit类得到图片的id和水果名,然后layout目录下新建fruit_item.xml,main_activity.xml下要添加ListView标签,接下来创建一个自定义的适配器,即创建一个新的类 (继承自ArrayAdapter),然后再修改mainactivity的代码。
适配器
FruitAdapter重写了父类的一组构造函数,用于将上下文、ListView子项布局的id和数据都传递进来。另外又重写了getView()方法,这个方法再每个子项杯滚动到屏幕内的时候会被调用。getView()方法:首先getItem()得到fruit的实例,然后使用LayoutInflater为这个子项加载我们传入的布局
public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name ;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
public class FruitAdapter extends ArrayAdapter<Fruit> {
private int resourceId;
public FruitAdapter(Context context, int textViewResourceId, List<Fruit> objects){
super(context ,textViewResourceId, objects);
resourceId = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);//获取当前的Fruit实例
View view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
return view;
}
}
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();//初始化水果数据
FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item,fruitList);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
private void initFruits() {
for (int i = 0; i<2; i++) {
Fruit appple = new Fruit("Apple", R.drawable.apple);
fruitList.add(appple);
Fruit banane = new Fruit("Banane", R.drawable.banane);
fruitList.add(banane);
Fruit orange = new Fruit("Apple", R.drawable.orange);
fruitList.add(orange);
Fruit watermelon = new Fruit("Apple", R.drawable.watermelon);
fruitList.add(watermelon);
Fruit pear = new Fruit("Apple", R.drawable.pear);
fruitList.add(pear);
Fruit grape = new Fruit("Apple", R.drawable.grape);
fruitList.add(grape);
Fruit pineapple = new Fruit("Apple", R.drawable.pineapple);
fruitList.add(pineapple);
Fruit strawbery = new Fruit("Apple", R.drawable.strawberry);
fruitList.add(strawbery);
Fruit cherry = new Fruit("Apple", R.drawable.cherry);
fruitList.add(cherry);
Fruit mango = new Fruit("Apple", R.drawable.mango);
fruitList.add(mango);
}
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list_view"/>
</LinearLayout>```
```xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="100dp"
android:layout_height="70dp"
/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"/>
</LinearLayout>
ImageView中
可以android:layout_width=“100dp”
android:layout_height="70dp"改变图片的大小
viewHolder的作用
viewholder的作用是因为Android有个recycler的反复循环器,viewholder就是借助他来做到循环利用itemview。
例如:
默认加载10个itemview,初始化的时候创建一个viewholder,并把10个itemview加载到内存里面。
接着下滑,加载5-15的item,这个时候,显示的还是只有10个view。
我们只是需要重新填充view的数据,而不需要再次创建view并加载到内存里面,这样就可以复用itemview而避免频繁创建view导致的内存消耗了。
结论:相当于只创建了一次view,其他时候都在复用view,只是更改了数据而已。
原文链接:
https://blog.csdn.net/hacker_crazy/article/details/103684421
RecycleView
(个人理解)
布局文件+适配器类+主活动类
布局文件有两个,main.xml添加RecyclerView控件,item.xml是每一个recyclerview的布局
适配器类是为RecyclerVIew准备一个适配器。该适配器继承自RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder。并在类中定义一个内部类,内部类的构造函数构造函数(第一个函数)传入一个参数view,然后通过findbyview获取imageview和textview的实例;第二个构造函数FruitAdapter用于传入数据源,并赋予一个全局变量mFruitList;第三个OnCreateViewHolder方法是用于创建一个ViewHolder实例,首先加载item.xml布局进来,然后创建一个ViewHolder实例,并把加载出来的布局传入构造函数中,最后返回ViewHolder实例;第四个方法onBindViewHolder方法用来绑定holder和数据,最后一个函数返回数据源的长度(recyclerview有多少子项)。
主活动类就是RecyclerView和数据之间关联。首先获取recyclerview实例,然后新建一个LinerLayoutManager(线性布局的意思)对象并把它设置到recyclerview中,再创建一个FruitAdapt适配器实例,将数据传入适配器里,最后setAdapter方法完成适配器的设置。另外还要准备数据。
第一步:添加RecyclerView
**方法1:**点开任意一个布局文件,找到左边的RecyclerView控件,点击旁边的按钮即可添加RecyclerView。
**方法2:**在add/build.gradle文件的dependencies中添加依赖
implementation 'androidx.recyclerview:recyclerview:1.1.0'
第二步:添加布局文件
在布局文件activity_main.xml中先添加RecyclerView控件
再添加一个item_list.xml的布局文件
```xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="70dp"
>
<ImageView
android:id="@+id/fruit_image"
android:layout_width="100dp"
android:layout_height="70dp"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
第三步:添加逻辑代码
新建FruitAdaoter类(准备一个自定义适配器)
//让这个适配器继承自RecyclerView.Adapter
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
//定义一个内部类ViewHolder 继承自RecycleView.ViewHolder
static class ViewHolder extends RecyclerView.ViewHolder{
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view) {
super(view);
//找到条目的控件
fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
fruitName = (TextView) view.findViewById(R.id.fruit_name);
}
}
public FruitAdapter(List<Fruit> fruitList) {
mFruitList = fruitList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//加载布局 拿到view 创建holder
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
//绑定holder 一般用于设置数据
public void onBindViewHolder(ViewHolder holder, int position) {
Fruit fruit = mFruitList.get(position);
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitName.setText(fruit.getName());
}
@Override
//返回条目的个数
public int getItemCount(){
return mFruitList.size();
}
}
第四步:Fruit类
public class Fruit {
private String name;
private int imageId;
public Fruit(String name, int imageId) {
this.name = name ;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
第五步:主活动类
public class MainActivity extends AppCompatActivity {
//创建数据集合
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById (R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
private void initFruits() {
//创建数据
for (int i = 0; i<2; i++) {
//创建对象
Fruit appple = new Fruit("Apple", R.drawable.apple);
fruitList.add(appple);
Fruit banane = new Fruit("Banane", R.drawable.banane);
fruitList.add(banane);
Fruit orange = new Fruit("Orange", R.drawable.orange);
fruitList.add(orange);
Fruit watermelon = new Fruit("Watermalon", R.drawable.watermelon);
fruitList.add(watermelon);
Fruit pear = new Fruit("Pear", R.drawable.pear);
fruitList.add(pear);
Fruit grape = new Fruit("Grape", R.drawable.grape);
fruitList.add(grape);
Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple);
fruitList.add(pineapple);
Fruit strawbery = new Fruit("Strawberry", R.drawable.strawberry);
fruitList.add(strawbery);
Fruit cherry = new Fruit("Cherry", R.drawable.cherry);
fruitList.add(cherry);
Fruit mango = new Fruit("Mango", R.drawable.mango);
fruitList.add(mango);
}
}
}
横向滚动:
修改main.xml的布局为垂直布局 orientation = “vertical” 宽度设为100dp imageview和textview的layout_gravity=“center_horizontal” ,textview的layout_marginTop=“10dp”(文本框上面隔开)
添加MainActivity中的代码
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
调用LinearLayoutManager的setOrientation()来设置布局的排列方式,默认纵向,LinearLayoutManager.HORIZONTAL表示布局横行排列
另外GridLayoutManager网络布局;StaggeredGridLayoutManager 瀑布流布局