阅读量:2
【Android】基础—基本布局
基本布局
线性布局
垂直方向:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 1"/> <Button android:id="@+id/button_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 2"/> <Button android:id="@+id/button_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 3"/> </LinearLayout>
水平方向:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 1"/> <Button android:id="@+id/button_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 2"/> <Button android:id="@+id/button_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 3"/> </LinearLayout>
指定控件大小
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/input_message" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="4" android:hint="请输入内容"/> <Button android:id="@+id/button_1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="发送"/> </LinearLayout>
当我们使用了android:layout_weight,控件宽度就不再由android:layout_width来决定,而是根据每个组件的数字进行比例划分(上面例子就是EditText : Button = 4 : 1)
相对布局
1. 相对于父容器的属性
android:layout_alignParentStart
:将控件的开始边(根据布局方向,可能是左边或右边)与父容器的开始边对齐。在支持从右到左(RTL)布局的语言环境中特别有用。android:layout_alignParentEnd
:将控件的结束边(同样根据布局方向)与父容器的结束边对齐。android:layout_alignParentBottom
:将控件的底部与父布局的底部对齐。android:layout_centerHorizontal
:将控件水平居中于父布局。android:layout_centerVertical
:将控件垂直居中于父布局。
2. 相对于兄弟控件的属性
android:layout_toLeftOf
:将控件放置于指定控件的左边。需要指定参照控件的ID(如@+id/someViewId
)。android:layout_toRightOf
:将控件放置于指定控件的右边。同样需要指定参照控件的ID。android:layout_above
:将控件放置于指定控件的上方。android:layout_below
:将控件放置于指定控件的下方。android:layout_alignTop
:将控件的顶部与指定控件的顶部对齐。android:layout_alignBottom
:将控件的底部与指定控件的底部对齐。android:layout_alignLeft
:将控件的左边缘与指定控件的左边缘对齐。android:layout_alignRight
:将控件的右边缘与指定控件的右边缘对齐。android:layout_alignStart
:将控件的开始边与指定控件的开始边对齐(考虑RTL布局)。android:layout_alignEnd
:将控件的结束边与指定控件的结束边对齐(考虑RTL布局)。
3. 其他常用属性
android:layout_width
和android:layout_height
:设置控件的宽度和高度。常用值包括wrap_content
(根据内容调整大小)、match_parent
(填充父容器的整个宽度/高度)和具体数值(如dp
、px
等)。android:layout_margin
及其子属性(如android:layout_marginLeft
、android:layout_marginTop
等):设置控件的外边距,即控件与其父容器或其他控件之间的空间。android:layout_gravity
:设置控件在其父容器中的对齐方式(尽管在RelativeLayout中,这个属性主要用于子布局或特定场景,因为RelativeLayout主要通过上述相对属性来控制位置)。
简单举例:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="button1" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:text="button2" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="button3" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentBottom="true" android:text="button4" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:text="button5" /> </RelativeLayout>
帧布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:text="HeHe" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:src="@mipmap/ic_launcher" /> </FrameLayout>
百分比布局
对FrameLayout和RelativeLayout进行扩展
扩展为PercentFrameLayout、PercentRelativeLayout
自定义布局
引入布局
如果我们把一个布局在多个活动中都要使用,那么就可以重新创建一个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="wrap_content"> <Button android:id="@+id/title_back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Back" android:textColor="#fff"/> <TextView android:id="@+id/title_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:gravity="center" android:text="标题" android:textColor="#fff" android:textSize="24sp"/> <Button android:id="@+id/title_edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Edit" android:textColor="#fff"/> </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"> <include layout="@layout/title"/> </LinearLayout>
隐藏自带的标题栏:
public class MainActivity extends AppCompatActivity { private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ActionBar actionBar = getSupportActionBar(); if(actionBar != null) { actionBar.hide(); } } }
自定义控件
// 定义一个名为TitleLayout的类,它继承自LinearLayout类,这意味着TitleLayout将拥有LinearLayout的所有属性和方法, // 并且可以额外添加自定义的功能或布局。 public class TitleLayout extends LinearLayout { // 定义一个构造函数,这个构造函数接收两个参数: // context:代表当前应用或活动的上下文,可以通过它访问资源和类加载器等。 // attrs:AttributeSet对象,包含了在XML布局文件中为当前视图指定的属性。 public TitleLayout(Context context, @Nullable AttributeSet attrs) { // 调用父类LinearLayout的构造函数,传入context和attrs参数,以便父类能够正确初始化。 super(context, attrs); // 使用LayoutInflater的from方法,传入context来获取一个LayoutInflater实例。 // LayoutInflater用于将layout资源文件中的视图布局填充到布局容器中。 // 这里,我们将R.layout.title布局文件的内容填充到当前TitleLayout实例中, // 因为TitleLayout继承自LinearLayout,所以可以直接将布局文件的内容添加到TitleLayout中。 // 注意:这里的this指的是当前正在创建的TitleLayout实例,表示将R.layout.title的内容填充到当前实例中。 LayoutInflater.from(context).inflate(R.layout.title, this); } // 注意:虽然在这个简单的例子中只有一个构造函数,但在实际应用中, // 通常还会添加一个只接收context参数的构造函数,以确保通过代码动态创建TitleLayout实例时不会出错。 // 例如: // public TitleLayout(Context context) { // super(context); // // 可以在这里进行额外的初始化操作,但通常不需要因为layout文件已经通过其他构造函数填充。 // } // 此外,还可以添加其他方法和属性来满足更复杂的需求。 }
然后将activity_main进行修改
<?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"> <com.example.practice_view.TitleLayout android:layout_width="match_parent" android:layout_height="wrap_content"/>` </LinearLayout>
ListView
<?xml version="1.0" encoding="utf-8"?> <!-- 声明这是一个XML文件,并指定其编码为UTF-8 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <!-- 定义LinearLayout的属性 --> android:id="@+id/main" <!-- 为LinearLayout设置一个唯一的ID,可以在Java或Kotlin代码中引用它 --> android:layout_width="match_parent" <!-- 设置LinearLayout的宽度为父容器的宽度 --> android:layout_height="match_parent"> <!-- 设置LinearLayout的高度为父容器的高度 --> <!-- 在LinearLayout内部定义一个ListView --> <ListView android:id="@+id/list_view" <!-- 为ListView设置一个唯一的ID,以便在Java或Kotlin代码中引用它 --> android:layout_width="wrap_content" <!-- 设置ListView的宽度为内容所需的最小宽度 --> android:layout_height="wrap_content"> <!-- 设置ListView的高度为内容所需的最小高度 --> </ListView> </LinearLayout>
public class MainActivity extends AppCompatActivity { private String[] data = {"Apple", "Banana", "Orange", "Watermelon", "Apple", "Banana", "Orange", "Watermelon" , "Apple", "Banana", "Orange", "Watermelon", "Apple", "Banana", "Orange", "Watermelon" , "Apple", "Banana", "Orange", "Watermelon", "Apple", "Banana", "Orange", "Watermelon"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 确保您的布局文件名为activity_main.xml // 创建一个ArrayAdapter来管理ListView的数据 ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, data); // 获取ListView的实例 ListView listView = (ListView) findViewById(R.id.list_view); // 将适配器设置给ListView listView.setAdapter(adapter); } }
定制界面
首先创建一个Fruit类,作为ListView的适配器:
package com.example.list; public class Fruit { private String name; private int imageId; public Fruit() { } public Fruit(String name, int imageId) { this.name = name; this.imageId = imageId; } public String getName() { return name; } public int getImageId() { return imageId; } }
然后需要为ListView子项指定一个我们的自定义布局,新建fruit_item.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="wrap_content"> <ImageView android:id="@+id/fruit_image" android:layout_width="200dp" android:layout_height="200dp"/> <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>
接下来需要创建一个自定义适配器,继承自ArrayAdapter,泛型指定为Fruit类,新建类FruitAdapter:
package com.example.list; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.List; public class FruitAdapter extends ArrayAdapter<Fruit> { private int resourceId; public FruitAdapter(@NonNull Context context, int textViewResourceId,@NonNull List<Fruit> objects) { super(context, textViewResourceId, objects); this.resourceId = textViewResourceId; } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { Fruit fruit = getItem(position); View view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image); TextView textView = (TextView) view.findViewById(R.id.fruit_name); fruitImage.setImageResource(fruit.getImageId()); textView.setText(fruit.getName()); return view; } }
修改MainActivity中的代码:
package com.example.list; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; 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); // 确保您的布局文件名为activity_main.xml initFruit(); FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList); ListView listView = (ListView) findViewById(R.id.list_view); listView.setAdapter(adapter); } private void initFruit() { for(int i = 0; i < 2; i++) { Fruit apple = new Fruit("Apple", R.drawable.apple); fruitList.add(apple); Fruit banana = new Fruit("Banana", R.drawable.banana); fruitList.add(banana); Fruit orange = new Fruit("Orange", R.drawable.orange); fruitList.add(orange); Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon); fruitList.add(watermelon); } } }
提升运行效率
可以对convertView进行判断是否为Null,如果空则加载布局,如果不为空则直接引用
public class FruitAdapter extends ArrayAdapter<Fruit> { private int resourceId; public FruitAdapter(@NonNull Context context, int textViewResourceId,@NonNull List<Fruit> objects) { super(context, textViewResourceId, objects); this.resourceId = textViewResourceId; } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { Fruit fruit = getItem(position); View view; if(convertView == null) view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); else view = convertView; ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image); TextView textView = (TextView) view.findViewById(R.id.fruit_name); fruitImage.setImageResource(fruit.getImageId()); textView.setText(fruit.getName()); return view; } }
还可以通过ViewHolder对控件实例进行缓存来提高效率:
package com.example.list; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class FruitAdapter extends ArrayAdapter<Fruit> { private int resourceId; public FruitAdapter(@NonNull Context context, int textViewResourceId,@NonNull List<Fruit> objects) { super(context, textViewResourceId, objects); this.resourceId = textViewResourceId; } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { Fruit fruit = getItem(position); View view; ViewHolder viewHolder; if(convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false); viewHolder = new ViewHolder(); viewHolder. fruitImage = (ImageView) view.findViewById(R.id.fruit_image); viewHolder. fruitName = (TextView) view.findViewById(R.id.fruit_name); view.setTag(viewHolder); } else { view = convertView; viewHolder = (ViewHolder) view.getTag(); } viewHolder.fruitImage.setImageResource(fruit.getImageId()); viewHolder.fruitName.setText(fruit.getName()); return view; } class ViewHolder { ImageView fruitImage; TextView fruitName; } }
点击事件
package com.example.list; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private List<Fruit> fruitList = new ArrayList<>(); @Override @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 调用父类的onCreate方法,完成Activity的初始化 setContentView(R.layout.activity_main); // 设置当前Activity的布局文件为activity_main.xml initFruit(); // 调用initFruit方法,初始化水果数据 FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList); // 创建FruitAdapter对象,传入当前上下文、布局文件和水果列表 ListView listView = (ListView) findViewById(R.id.list_view); // 获取布局文件中的ListView控件 listView.setAdapter(adapter); // 为ListView设置适配器 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { // 为ListView设置项点击事件监听器 @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Fruit fruit = fruitList.get(position); // 获取点击的水果项 Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show(); // 显示水果名称的Toast消息 } }); } private void initFruit() { for(int i = 0; i < 2; i++) { Fruit apple = new Fruit("Apple", R.drawable.apple); fruitList.add(apple); Fruit banana = new Fruit("Banana", R.drawable.banana); fruitList.add(banana); Fruit orange = new Fruit("Orange", R.drawable.orange); fruitList.add(orange); Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon); fruitList.add(watermelon); } } }
RecyclerView
FruitAdapter
package com.example.list; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import java.util.List; // 定义FruitAdapter类,继承自RecyclerView.Adapter,使用内部类ViewHolder public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> { private List<Fruit> mFruitList; // 保存水果数据的列表 // 定义ViewHolder内部类,继承自RecyclerView.ViewHolder public class ViewHolder extends RecyclerView.ViewHolder { ImageView fruitImage; // 用于显示水果图片的ImageView TextView fruitName; // 用于显示水果名称的TextView // ViewHolder的构造方法,接收一个View参数并初始化内部控件 public ViewHolder(View view) { super(view); fruitImage = (ImageView) view.findViewById(R.id.fruit_image); // 通过ID获取ImageView控件 fruitName = (TextView) view.findViewById(R.id.fruit_name); // 通过ID获取TextView控件 } } // FruitAdapter的构造方法,接收一个水果列表 public FruitAdapter(List<Fruit> fruitList) { mFruitList = fruitList; // 初始化水果列表 } @NonNull @Override // 创建ViewHolder实例,加载item布局 public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // 使用LayoutInflater加载fruit_item布局文件 View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false); ViewHolder holder = new ViewHolder(view); // 创建ViewHolder实例 return holder; // 返回ViewHolder实例 } @Override // 将数据绑定到ViewHolder上 public void onBindViewHolder(@NonNull ViewHolder holder, int position) { Fruit fruit = mFruitList.get(position); // 根据position获取当前项的水果对象 holder.fruitImage.setImageResource(fruit.getImageId()); // 设置水果图片资源 holder.fruitName.setText(fruit.getName()); // 设置水果名称 } @Override // 返回数据项的总数 public int getItemCount() { return mFruitList.size(); // 返回水果列表的大小 } }
MainActivity
package com.example.list; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; 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); initFruit(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(linearLayoutManager); FruitAdapter adapter = new FruitAdapter(fruitList); recyclerView.setAdapter(adapter); } private void initFruit() { for(int i = 0; i < 4; i++) { Fruit apple = new Fruit("Apple", R.drawable.apple); fruitList.add(apple); Fruit banana = new Fruit("Banana", R.drawable.banana); fruitList.add(banana); Fruit orange = new Fruit("Orange", R.drawable.orange); fruitList.add(orange); Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon); fruitList.add(watermelon); } } }
横向滚动和瀑布流布局
横向滚动
在fruit_item中进行修改:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"//垂直排布 android:layout_width="100dp" android:layout_height="wrap_content"> <ImageView android:id="@+id/fruit_image" android:layout_width="20dp" android:layout_height="20dp" android:layout_gravity="center_vertical"/> <TextView android:id="@+id/fruit_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginTop="10dp"/> </LinearLayout>
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initFruit(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);//布局横向排列 recyclerView.setLayoutManager(linearLayoutManager); FruitAdapter adapter = new FruitAdapter(fruitList); recyclerView.setAdapter(adapter); }
瀑布流布局
package com.example.list; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.StaggeredGridLayoutManager; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; 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); initFruit(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);//用法在下面 recyclerView.setLayoutManager(layoutManager); FruitAdapter adapter = new FruitAdapter(fruitList); recyclerView.setAdapter(adapter); } private void initFruit() { for(int i = 0; i < 4; i++) { Fruit apple = new Fruit("Apple", R.drawable.apple); fruitList.add(apple); Fruit banana = new Fruit("Banana", R.drawable.banana); fruitList.add(banana); Fruit orange = new Fruit("Orange", R.drawable.orange); fruitList.add(orange); Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon); fruitList.add(watermelon); } } }
StaggeredGridLayoutManager参数解释:
列数 (
spanCount
):StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, ...);
- 参数
3
指定了网格的列数。这意味着RecyclerView
将会有3列。如果是水平布局,则是行数。
- 参数
方向 (
orientation
):StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(..., StaggeredGridLayoutManager.VERTICAL);
- 参数
StaggeredGridLayoutManager.VERTICAL
指定了网格的方向。 StaggeredGridLayoutManager.VERTICAL
表示垂直方向布局,每一列的项从上到下排列。StaggeredGridLayoutManager.HORIZONTAL
表示水平方向布局,每一行的项从左到右排列。
- 参数
网格布局
网格布局就是对瀑布流布局进行简单修改就能实现:
package com.example.list; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.StaggeredGridLayoutManager; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; 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); initFruit(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); GridLayoutManager layoutManager = new GridLayoutManager(this, 3);//修改位置 recyclerView.setLayoutManager(layoutManager); FruitAdapter adapter = new FruitAdapter(fruitList); recyclerView.setAdapter(adapter); } private void initFruit() { for(int i = 0; i < 4; i++) { Fruit apple = new Fruit("Apple", R.drawable.apple); fruitList.add(apple); Fruit banana = new Fruit("Banana", R.drawable.banana); fruitList.add(banana); Fruit orange = new Fruit("Orange", R.drawable.orange); fruitList.add(orange); Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon); fruitList.add(watermelon); } } }
点击事件
通过获取用户点击的position拿到相应的Fruit实例,弹出不同的内容
package com.example.list; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> { private List<Fruit> mFruitList; public class ViewHolder extends RecyclerView.ViewHolder { View fruitView; ImageView fruitImage; TextView fruitName; public ViewHolder(View view) { super(view); fruitView = view; fruitImage = (ImageView) view.findViewById(R.id.fruit_image); fruitName = (TextView) view.findViewById(R.id.fruit_name); } } public FruitAdapter(List<Fruit> fruitList) { mFruitList = fruitList; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false); final ViewHolder holder = new ViewHolder(view); holder.fruitView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = holder.getAdapterPosition(); Fruit fruit = mFruitList.get(position); Toast.makeText(v.getContext(),"你选择了文字" + fruit.getName(), Toast.LENGTH_SHORT).show(); } }); holder.fruitImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = holder.getAdapterPosition(); Fruit fruit = mFruitList.get(position); Toast.makeText(v.getContext(), "你选择了图片" + fruit.getName(), Toast.LENGTH_SHORT).show(); } }); return holder; } @Override public void onBindViewHolder(@NonNull 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(); } }
已经到底啦!!