【Android】基础—基本布局

【Android】基础---基本布局

基本布局

线性布局

垂直方向

xml 复制代码
<?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 复制代码
<?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 复制代码
<?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_widthandroid:layout_height :设置控件的宽度和高度。常用值包括wrap_content(根据内容调整大小)、match_parent(填充父容器的整个宽度/高度)和具体数值(如dppx等)。
  • android:layout_margin 及其子属性(如android:layout_marginLeftandroid:layout_marginTop等):设置控件的外边距,即控件与其父容器或其他控件之间的空间。
  • android:layout_gravity:设置控件在其父容器中的对齐方式(尽管在RelativeLayout中,这个属性主要用于子布局或特定场景,因为RelativeLayout主要通过上述相对属性来控制位置)。

简单举例:

xml 复制代码
<?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 复制代码
<?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 复制代码
<?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 复制代码
<?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>

隐藏自带的标题栏:

java 复制代码
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();
        }
    }
}

自定义控件

java 复制代码
// 定义一个名为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 复制代码
<?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 复制代码
<?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>
java 复制代码
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的适配器:

java 复制代码
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 复制代码
<?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:

java 复制代码
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中的代码:

java 复制代码
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,如果空则加载布局,如果不为空则直接引用

java 复制代码
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对控件实例进行缓存来提高效率:

java 复制代码
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;
    }
}

点击事件

java 复制代码
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

java 复制代码
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

java 复制代码
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中进行修改:

java 复制代码
<?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>
java 复制代码
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);
    }

瀑布流布局

java 复制代码
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参数解释:

  1. 列数 (spanCount):

    java 复制代码
    StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, ...);
    • 参数 3 指定了网格的列数。这意味着 RecyclerView 将会有3列。如果是水平布局,则是行数。
  2. 方向 (orientation):

    java 复制代码
    StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(..., StaggeredGridLayoutManager.VERTICAL);
    • 参数 StaggeredGridLayoutManager.VERTICAL 指定了网格的方向。
    • StaggeredGridLayoutManager.VERTICAL 表示垂直方向布局,每一列的项从上到下排列。
    • StaggeredGridLayoutManager.HORIZONTAL 表示水平方向布局,每一行的项从左到右排列。

网格布局

网格布局就是对瀑布流布局进行简单修改就能实现:

java 复制代码
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实例,弹出不同的内容

java 复制代码
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();
    }

}

已经到底啦!!

相关推荐
Yeats_Liao14 分钟前
Spring 定时任务:@Scheduled 注解四大参数解析
android·java·spring
雾里看山2 小时前
【MySQL】 库的操作
android·数据库·笔记·mysql
水瓶丫头站住11 小时前
安卓APP如何适配不同的手机分辨率
android·智能手机
xvch11 小时前
Kotlin 2.1.0 入门教程(五)
android·kotlin
xvch15 小时前
Kotlin 2.1.0 入门教程(七)
android·kotlin
望风的懒蜗牛15 小时前
编译Android平台使用的FFmpeg库
android
浩宇软件开发16 小时前
Android开发,待办事项提醒App的设计与实现(个人中心页)
android·android studio·android开发
ac-er888816 小时前
Yii框架中的多语言支持:如何实现国际化
android·开发语言·php
苏金标17 小时前
The maximum compatible Gradle JVM version is 17.
android
zhangphil17 小时前
Android BitmapShader简洁实现马赛克,Kotlin(一)
android·kotlin