Android 开发 - 控件(ConstraintLayout、Guideline、SeekBar、Chronometer、RecyclerView、Toolbar)
Android 开发 - 控件(ConstraintLayout、Guideline、SeekBar、Chronometer、RecyclerView、Toolbar)
一、ConstraintLayout
1、基本介绍
- ConstraintLayout 是 Android 开发中一种非常强大且灵活的布局管理器,它允许通过约束(Constraints)来定义视图(View)之间的相对位置和尺寸关系,与传统的布局方式(例如,LinearLayout、RelativeLayout)相比,ConstraintLayout 提供了更高的性能和更精细的布局控制,ConstraintLayout 有如下特点
-
性能优化:由于减少了嵌套布局的数量,ConstraintLayout 通常比传统的布局方式具有更好的性能
-
直观且灵活的布局定义:可以使用视觉编辑器或代码来定义视图的约束,从而轻松创建复杂的布局结构
-
支持扁平化布局:通过减少布局嵌套层级,有助于减少视图层次结构,提高渲染性能
- 在 ConstraintLayout 中,可以使用一系列类似的属性来定义视图之间的水平和垂直对齐关系,这些属性以 layout_constraint 开头,后面跟着一个表示边缘(例如,left、right、top、bottom、start、end)的字符串,然后是另一个表示对齐关系的字符串(例如,leftOf、rightOf、topOf、bottomOf、startOf、endOf),最后是 parent 或者另一个视图的 ID
属性 | 说明 |
---|---|
layout_constraintLeft_toLeftOf | 将当前视图的左侧边缘与另一个视图的左侧边缘对齐 |
layout_constraintLeft_toRightOf | 将当前视图的左侧边缘与另一个视图的右侧边缘对齐 |
layout_constraintRight_toLeftOf | 将当前视图的右侧边缘与另一个视图的左侧边缘对齐 |
layout_constraintRight_toRightOf | 将当前视图的右侧边缘与另一个视图的右侧边缘对齐 |
layout_constraintTop_toTopOf | 将当前视图的顶部边缘与另一个视图的顶部边缘对齐 |
layout_constraintTop_toBottomOf | 将当前视图的顶部边缘与另一个视图的底部边缘对齐 |
layout_constraintBottom_toTopOf | 将当前视图的底部边缘与另一个视图的顶部边缘对齐 |
layout_constraintBottom_toBottomOf | 将当前视图的底部边缘与另一个视图的底部边缘对齐 |
layout_constraintHorizontal_bias | 用于调整视图在其水平约束范围内的偏移量 它接收一个 0.0 ~ 1.0 的浮点数值,表示视图应该偏向其水平约束边界的百分比 |
layout_constraintVertical_bias | 用于调整视图在其垂直约束范围内的偏移量 它接收一个 0.0 ~ 1.0 的浮点数值,表示视图应该偏向其垂直约束边界的百分比 |
- 除此以外还有一些属性,它们考虑到了从右到左的语言环境(例如,阿拉伯语),在这些环境中,视图的开始(Start)和结束(End)方向可能与常规从左到右的语言环境(例如,英语)相反
属性 | 说明 |
---|---|
layout_constraintStart_toStartOf | 将当前视图的开始边缘与另一个视图的开始边缘对齐 |
layout_constraintStart_toEndOf | 将当前视图的开始边缘与另一个视图的结束边缘对齐 |
layout_constraintEnd_toStartOf | 将当前视图的结束边缘与另一个视图的开始边缘对齐 |
layout_constraintEnd_toEndOf | 将当前视图的结束边缘与另一个视图的结束边缘对齐 |
2、演示
- activity_constraint_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ConstraintLayoutActivity">
<Button
android:id="@+id/button_confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确定"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/button_cancel"
app:layout_constraintHorizontal_bias="0.5"/>
<Button
android:id="@+id/button_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
app:layout_constraintTop_toTopOf="@id/button_confirm"
app:layout_constraintBottom_toBottomOf="@id/button_confirm"
app:layout_constraintLeft_toRightOf="@id/button_confirm"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.5"/>
</androidx.constraintlayout.widget.ConstraintLayout>
二、Guideline
1、基本介绍
- Guideline 是 ConstraintLayout 中的一个组件,它用于在布局中创建一条不可见的线,用于辅助其他视图组件的对齐和定位,Guideline 本身并不显示任何内容,它可以作为其他视图的参考点,Guideline 有三个重要的属性,但每个 Guideline 只能指定其中一个
属性 | 说明 |
---|---|
layout_constraintGuide_begin | 用于指定 Guideline 左侧或顶部的固定距离 |
layout_constraintGuide_end | 用于指定 Guideline 右侧或底部的固定距离 |
layout_constraintGuide_percent | 用于指定 Guideline 在父控件中的宽度或高度的百分比位置 例如设置为 0.8,则 Guideline 会出现在距离顶部或左侧 80% 的位置 |
2、演示
- activity_guideline_1.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".GuidelineActivity">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确定"
app:layout_constraintRight_toLeftOf="@id/guide"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginRight="50dp"
android:layout_marginTop="200dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
app:layout_constraintLeft_toRightOf="@id/guide"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="50dp"
android:layout_marginTop="200dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
- activity_guideline_2.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".GuidelineActivity">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确定"
app:layout_constraintBottom_toTopOf="@id/guide"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginBottom="200dp"
android:layout_marginLeft="200dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
app:layout_constraintTop_toBottomOf="@id/guide"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="200dp"
android:layout_marginLeft="200dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
- activity_guideline_3.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".GuidelineActivity">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.75" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确定"
app:layout_constraintLeft_toRightOf="@id/guide_2"
app:layout_constraintBottom_toTopOf="@id/guide_1"
android:layout_marginBottom="200dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="确定"
app:layout_constraintLeft_toRightOf="@id/guide_2"
app:layout_constraintTop_toBottomOf="@id/guide_1"
android:layout_marginTop="200dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
三、SeekBar
1、基本介绍
- SeekBar 是 Android 中一个常用的 UI 组件,它允许用户通过拖动滑块来选择一个范围内的值,SeekBar 通常用于音量控制、进度显示等场景,SeekBar 的基本属性如下
属性 | 说明 |
---|---|
max | 设置 SeekBar 的最大值 |
min | 设置 SeekBar 的最小值 |
progress | 设置或获取 SeekBar 当前进度值 |
thumb | 设置或获取滑块的图标 |
2、演示
(1)Activity Layout
- activity_seek_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".SeekBarActivity">
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="50"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- SeekBarActivity.java
package com.my.jetpackdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.SeekBar;
public class SeekBarActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seek_bar);
SeekBar seekBar = findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// 当进度改变时调用
// fromUser 表示是否由用户操作引起
Log.d("SeekBar", "Progress: " + progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 当用户开始拖动滑块时调用
Log.d("SeekBar", "Start Tracking");
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 当用户停止拖动滑块时调用
Log.d("SeekBar", "Stop Tracking");
}
});
}
}
四、Chronometer
1、基本介绍
-
Chronometer 是一个计时器控件,它继承自 TextView,并可以通过 1 秒的时间间隔进行计时,并显示出计时结果。这个组件在 Android 开发中可以用于实现对时间的监测,包括开始计时、停止计时、重新计时以及设置计时模式等功能
-
Chronometer 的计时原理相对简单,它内部有一个 Handler 负责定时更新 UI,首先,通过
setBase(long t)
设置好基准时间,当调用 start 方法时,每隔一秒,使用当前的SystemClock.elapsedRealtime()
减去基准时间,得到的逝去时间就会显示在 TextView 中 -
SystemClock.elapsedRealtime()
是 Android 系统中用于获取系统启动后经过的毫秒数的一个方法,它返回的是一个 long 类型的值,表示从系统启动到现在所经过的时间
2、演示
(1)Activity Layout
- activity_chronometer_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ChronometerTestActivity">
<Chronometer
android:id="@+id/chronometer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteY="0dp" />
<Button
android:id="@+id/start_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:text="Start"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chronometer"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/stop_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Stop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/start_button"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/reset_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Rest"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stop_button"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- ChronometerTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.Chronometer;
public class ChronometerTestActivity extends AppCompatActivity {
private Chronometer chronometer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chronometer_test);
chronometer = findViewById(R.id.chronometer);
Button startButton = findViewById(R.id.start_button);
Button stopButton = findViewById(R.id.stop_button);
Button resetButton = findViewById(R.id.reset_button);
// 设置基准时间
chronometer.setBase(SystemClock.elapsedRealtime());
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
chronometer.start();
}
});
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
chronometer.stop();
}
});
resetButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 重置基准时间,实现重置计时
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
}
});
}
}
五、RecyclerView
1、基本使用
(1)Entity
- News.java
package com.my.otherlayout.entity;
public class News {
public String title;
public String content;
public News(String title, String content) {
this.title = title;
this.content = content;
}
}
(2)Activity Layout
- my_recycler_view_demo_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:paddingTop="20dp"
android:paddingBottom="20dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="标题" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="内容" />
</androidx.constraintlayout.widget.ConstraintLayout>
- activity_my_recycler_view_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MyRecyclerViewDemoActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp"
tools:ignore="MissingConstraints">
<Button
android:id="@+id/btn_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:onClick="addItem"
android:text="Add" />
<Button
android:id="@+id/btn_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:onClick="deleteItem"
android:text="Delete" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="48dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
(3)Adapter
- MyRecyclerViewDemoAdapter.java
package com.my.otherlayout.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.my.otherlayout.R;
import com.my.otherlayout.entity.News;
import java.util.List;
public class MyRecyclerViewDemoAdapter extends RecyclerView.Adapter<MyRecyclerViewDemoAdapter.MyRecyclerViewDemoViewHolder> {
private Context context;
private List<News> newsList;
public MyRecyclerViewDemoAdapter(Context context, List<News> newsList) {
this.context = context;
this.newsList = newsList;
}
@NonNull
@Override
public MyRecyclerViewDemoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.my_recycler_view_demo_item, null);
MyRecyclerViewDemoViewHolder myRecyclerViewDemoViewHolder = new MyRecyclerViewDemoViewHolder(view);
return myRecyclerViewDemoViewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyRecyclerViewDemoViewHolder holder, @SuppressLint("RecyclerView") int position) {
News news = newsList.get(position);
holder.tvTitle.setText(news.title);
holder.tvContent.setText(news.content);
}
@Override
public int getItemCount() {
return newsList.size();
}
static class MyRecyclerViewDemoViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle;
TextView tvContent;
ConstraintLayout item;
public MyRecyclerViewDemoViewHolder(@NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tv_title);
tvContent = itemView.findViewById(R.id.tv_content);
item = itemView.findViewById(R.id.item);
}
}
}
(4)Activity Code
- MyRecyclerViewDemoActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import com.my.otherlayout.adapter.MyRecyclerViewDemoAdapter;
import com.my.otherlayout.entity.News;
import java.util.ArrayList;
import java.util.List;
public class MyRecyclerViewDemoActivity extends AppCompatActivity {
private RecyclerView rv;
private List<News> newsList;
private MyRecyclerViewDemoAdapter myRecyclerViewDemoAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_recycler_view_demo);
rv = findViewById(R.id.rv);
newsList = new ArrayList<>();
for (int i = 0; i < 50; i++) {
News news = new News("标题 " + i, "内容 " + i);
newsList.add(news);
}
myRecyclerViewDemoAdapter = new MyRecyclerViewDemoAdapter(this, newsList);
rv.setAdapter(myRecyclerViewDemoAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
rv.setLayoutManager(linearLayoutManager);
}
public void addItem(View view) {
News news = new News("标题 新内容", "内容 新内容");
newsList.add(1, news);
myRecyclerViewDemoAdapter.notifyItemInserted(1);
}
public void deleteItem(View view) {
newsList.remove(1);
myRecyclerViewDemoAdapter.notifyItemMoved(0, 1);
}
}
2、高阶应用
(1)布局管理器
- LinearLayoutManager 线性布局管理器
// 竖向
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
rv.setLayoutManager(linearLayoutManager);
// 横向
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(RecyclerView.HORIZONTAL);
rv.setLayoutManager(linearLayoutManager);
- StaggeredGridLayoutManager 瀑布流布局管理器
// 竖向
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
rv.setLayoutManager(staggeredGridLayoutManager);
// 横向
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.HORIZONTAL);
rv.setLayoutManager(staggeredGridLayoutManager);
- GridLayoutManager 网格布局管理器
// 竖向
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
rv.setLayoutManager(gridLayoutManager);
// 横向
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
gridLayoutManager.setOrientation(RecyclerView.HORIZONTAL);
rv.setLayoutManager(gridLayoutManager);
(2)Item 分隔线
// 竖向
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
rv.setLayoutManager(linearLayoutManager);
DividerItemDecoration mDivider = new
DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
rv.addItemDecoration(mDivider);
// 横向
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(RecyclerView.HORIZONTAL);
rv.setLayoutManager(linearLayoutManager);
DividerItemDecoration mDivider = new
DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL);
rv.addItemDecoration(mDivider);
(3)Item 动画
- RecyclerView 本身具有默认的item动画配置,当动态添加或删除 item 时,RecyclerView 会自动应用这些动画效果,以增强用户体验,不过也可以自定义这些动画
DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
defaultItemAnimator.setAddDuration(1000);
defaultItemAnimator.setRemoveDuration(1000);
rv.setItemAnimator(defaultItemAnimator);
(4)Item 点击
-
对整个 Item 文件的根布局添加 id 属性
android:id="@+id/item"
-
在适配器中对其绑定点击事件
@Override
public void onBindViewHolder(@NonNull MyRecyclerViewDemoViewHolder holder, @SuppressLint("RecyclerView") int position) {
News news = newsList.get(position);
holder.tvTitle.setText(news.title);
holder.tvContent.setText(news.content);
holder.item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "点击了:" + position, Toast.LENGTH_SHORT).show();
}
});
}
六、Toolbar
1、Activity Layout
- 系统有自带的 Toolbar,想使用自定义的 Toolbar 需要编辑 values/themes.xml 文件,即不使用系统自带的 Toolbar
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.JetpackDemo" parent="Theme.MaterialComponents.DayNight.NoActionBar">
...
</style>
</resources>
- activity_tool_bar_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ToolBarTestActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#ffff00"
app:layout_constraintTop_toTopOf="parent"
app:logo="@mipmap/ic_launcher"
app:navigationIcon="@drawable/arrow_left"
app:title="Toolbar Test"
app:titleMarginStart="100dp"
app:titleTextColor="#ff0000"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="0dp" />
<!-- 标题居中 -->
<androidx.appcompat.widget.Toolbar
android:id="@+id/tb_title_center"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginTop="80dp"
android:background="#ffff00"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tb"
app:navigationIcon="@drawable/arrow_left"
tools:ignore="MissingConstraints">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="20dp"
android:text="Toolbar Test" />
</androidx.appcompat.widget.Toolbar>
</androidx.constraintlayout.widget.ConstraintLayout>
2、Activity Code
- ToolBarTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class ToolBarTestActivity extends AppCompatActivity {
public static final String TAG = "ToolBarTestActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tool_bar_test);
Toolbar tb = findViewById(R.id.tb);
tb.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG, "返回图标被点击了");
}
});
}
}
七、SurfaceView
1、演示
(1)Activity Layout
- activity_surface_view_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:background="#8BC34A"
tools:context=".SurfaceViewTestActivity">
<SurfaceView
android:id="@+id/sv"
android:layout_width="300dp"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- SurfaceViewTestActivity.java
package com.my.otherlayout;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class SurfaceViewTestActivity extends AppCompatActivity {
private SurfaceView sv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_surface_view_test);
sv = findViewById(R.id.sv);
// 获取 SurfaceHolder,并设置回调
sv.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
// 创建画笔
Paint paint = new Paint();
paint.setColor(Color.RED);
Canvas canvas = null;
try {
// 锁定画布并获取 Canvas 对象
canvas = holder.lockCanvas();
if (canvas != null) {
// 在这里执行绘图操作
// 画布画白
canvas.drawColor(Color.WHITE);
// 绘制一个矩形
canvas.drawRect(50, 50, 200, 200, paint);
}
} finally {
// 无论是否出现异常,都要解锁画布
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
// Surface 大小或格式改变时的处理逻辑(可选)
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
// Surface 销毁时的处理逻辑(可选)
}
});
}
}
2、SurfaceView 简化
(1)SurfaceView
- MySurfaceView.java
package com.my.otherlayout.surfaceview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import androidx.annotation.NonNull;
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
// 获取 SurfaceHolder,并设置回调
getHolder().addCallback(this);
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
// 创建画笔
Paint paint = new Paint();
paint.setColor(Color.RED);
Canvas canvas = null;
try {
// 锁定画布并获取 Canvas 对象
canvas = holder.lockCanvas();
if (canvas != null) {
// 在这里执行绘图操作
// 画布画白
canvas.drawColor(Color.WHITE);
// 绘制一个矩形
canvas.drawRect(50, 50, 200, 200, paint);
}
} finally {
// 无论是否出现异常,都要解锁画布
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {}
}
(2)Activity Layout
- activity_surface_view_simple_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:background="#8BC34A"
tools:context=".SurfaceViewSimpleTestActivity">
<com.my.otherlayout.surfaceview.MySurfaceView
android:id="@+id/sv"
android:layout_width="300dp"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(3)Activity Code
- SurfaceViewSimpleTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class SurfaceViewSimpleTestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_surface_view_simple_test);
}
}
八、FrameLayout
1、基本介绍
- FrameLayout 是 Android 中的一个基础布局类,它允许堆叠多个视图在一个屏幕上,并且这些视图会相互覆盖,FrameLayout 中的视图按照它们在布局文件中声明的顺序堆叠,后声明的视图会覆盖先声明的视图
2、演示
<?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="center"
android:background="#FF0000"
android:text="这是第一个 TextView"
android:textColor="#FFFFFF"
android:textSize="24sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#00FF00"
android:text="这是第二个 TextView"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:layout_marginTop="20dp"/>
</FrameLayout>
九、TableLayout
1、基本介绍
- TableLayout 是 Android 中用于创建表格布局的一个视图组(ViewGroup),它允许以行和列的形式组织子视图,每个 TableRow 对象代表表格中的一行,而每个 TableRow 又可以包含多个视图,这些视图将作为该行中的单元格
2、演示
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="*">
<TableRow>
<TextView
android:text="姓名"
android:padding="3dp" />
<TextView
android:text="年龄"
android:padding="3dp" />
</TableRow>
<TableRow>
<TextView
android:text="张三"
android:padding="3dp" />
<TextView
android:text="25"
android:padding="3dp" />
</TableRow>
<TableRow>
<TextView
android:text="李四"
android:padding="3dp" />
<TextView
android:text="30"
android:padding="3dp" />
</TableRow>
</TableLayout>
十、AbsoluteLayout
1、基本介绍
- AbsoluteLayout 是 Android 中一个较旧的布局管理器,它允许您直接指定子视图的 x 和 y 坐标位置,然而,由于 AbsoluteLayout 不支持不同屏幕大小和密度的灵活性,它已经被废弃并在 Android API 级别 3(Android 1.5)之后的版本中被标记为过时,因此,在现代 Android 开发中,不建议使用 AbsoluteLayout
2、演示
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="按钮 1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="10dp"
android:layout_y="10dp" />
<Button
android:text="按钮 2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="100dp"
android:layout_y="100dp" />
<TextView
android:text="这是一个文本视图"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="50dp"
android:layout_y="50dp" />
</AbsoluteLayout>
十一、ProgressBar
1、基本介绍
- ProgressBar 用于在用户界面中显示一个进度条,以告知用户某个操作正在进行中,ProgressBar 可以是圆形的也可以是水平的,可以通过设置它的样式属性来决定它是圆形的还是水平的
属性 | 说明 |
---|---|
max | 进度条的最大值 |
progress | 进度条的初始值 |
style | 进度条的样式 |
样式 | 说明 |
---|---|
progressBarStyleSmall | 小型的圆形进度条 |
progressBarStyleHorizontal | 水平的进度条 |
progressBarStyle | - |
2、演示
(1)Activity Layout
- activity_progress_bar_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ProgressBarTestActivity">
<ProgressBar
android:id="@+id/pb1"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ProgressBar
android:id="@+id/pb2"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:max="100"
android:progress="50"
app:layout_constraintBottom_toTopOf="@+id/pb1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ProgressBar
android:id="@+id/pb3"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
app:layout_constraintBottom_toTopOf="@+id/pb2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btn_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:onClick="show"
android:text="show"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_hide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:onClick="hide"
android:text="hide"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_show" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- ProgressBarTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
public class ProgressBarTestActivity extends AppCompatActivity {
private ProgressBar pb1;
private ProgressBar pb2;
private ProgressBar pb3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress_bar_test);
pb1 = findViewById(R.id.pb1);
pb2 = findViewById(R.id.pb2);
pb3 = findViewById(R.id.pb3);
}
public void show(View view) {
pb1.setVisibility(View.VISIBLE);
pb2.setVisibility(View.VISIBLE);
pb3.setVisibility(View.VISIBLE);
}
public void hide(View view) {
pb1.setVisibility(View.GONE);
pb2.setVisibility(View.GONE);
pb3.setVisibility(View.GONE);
}
}
十二、AutoCompleteTextView
1、基本介绍
- AutoCompleteTextView 控件允许用户输入文本,并自动显示一个下拉列表,这个列表包含了与用户输入匹配的预定义建议
2、演示
(1)Activity Layout
- activity_auto_complete_text_view_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".AutoCompleteTextViewTestActivity">
<AutoCompleteTextView
android:id="@+id/autoCompleteTextView"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- AutoCompleteTextViewTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
public class AutoCompleteTextViewTestActivity extends AppCompatActivity {
private AutoCompleteTextView autoCompleteTextView;
private String[] suggestions = {"Apple", "ApApple", "Banana", "BaBanana", "Cherry", "ChCherry"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auto_complete_text_view_test);
autoCompleteTextView = findViewById(R.id.autoCompleteTextView);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, suggestions);
autoCompleteTextView.setAdapter(adapter);
}
}
十三、TextInputLayout
1、基本介绍
- TextInputLayout 控件提供了一些方式来增强标准的 EditText 控件,提供如下额外的功能和视觉效果
-
浮动标签:当 EditText 获得焦点时,标签会浮动到 EditText 的上方,为用户提供一个明确的提示
-
错误消息显示:当 EditText 中的输入不满足某些条件时,可以在 TextInputLayout 下方显示一个错误消息
-
字符计数:可以显示 EditText 中的字符数,用于限制输入长度的场景
2、演示
(1)Activity Layout
- activity_text_input_layout_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".TextInputLayoutTestActivity">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterMaxLength="10"
app:hintEnabled="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/textInputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入内容" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getInputText"
android:text="获取输入内容"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- TextInputLayoutTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
public class TextInputLayoutTestActivity extends AppCompatActivity {
public static final String TAG = TextInputLayoutTestActivity.class.getSimpleName();
private TextInputLayout textInputLayout;
private TextInputEditText textInputEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_input_layout_test);
textInputLayout = findViewById(R.id.textInputLayout);
textInputEditText = findViewById(R.id.textInputEditText);
}
public void getInputText(View view) {
// 获取输入内容
String inputText = textInputEditText.getText().toString();
Log.i(TAG, "------------------------------ inputText: " + inputText);
}
}
十四、Chip
1、基本介绍
- Chip 是 Android 开发中用于表示一个紧凑的、可交互的元素的组件,通常用于表示标签
2、演示
(1)Activity Layout
- ChipTestActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ChipTestActivity">
<com.google.android.material.chip.Chip
android:id="@+id/chip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标签"
android:checkable="true"
app:chipStrokeWidth="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- ChipTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CompoundButton;
import com.google.android.material.chip.Chip;
public class ChipTestActivity extends AppCompatActivity {
public static final String TAG = ChipTestActivity.class.getSimpleName();
private Chip chip;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chip_test);
chip = findViewById(R.id.chip);
chip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG, "------------------------------ 点击了");
}
});
chip.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.i(TAG, "------------------------------ " + (isChecked ? "被选中" : "未被选中"));
}
});
}
}
十五、ChipGroup
1、基本介绍
- ChipGroup 是 Android 中用于组织和管理多个 Chip 组件的容器,通过将 Chip 放置在 ChipGroup 中,可以更轻松地控制它们的布局和交互行为,ChipGroup 提供了对齐方式、间距等属性,使得多个 Chip 的展示更加整齐和一致
2、演示
(1)Activity Layout
- activity_chip_group_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ChipGroupTestActivity">
<com.google.android.material.chip.ChipGroup
android:id="@+id/cg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:singleSelection="true">
<com.google.android.material.chip.Chip
android:id="@+id/chip1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:text="标签 1" />
<com.google.android.material.chip.Chip
android:id="@+id/chip2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:text="标签 2" />
</com.google.android.material.chip.ChipGroup>
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- ChipGroupTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;
public class ChipGroupTestActivity extends AppCompatActivity {
public static final String TAG = ChipGroupTestActivity.class.getSimpleName();
private ChipGroup cg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chip_group_test);
cg = findViewById(R.id.cg);
cg.setOnCheckedChangeListener(new ChipGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(ChipGroup group, int checkedId) {
for (int i = 0; i < group.getChildCount(); i++) {
Chip chip = (Chip) group.getChildAt(i);
if (chip.getId() == checkedId) {
Log.i(TAG, "------------------------------ 选中了:" + chip.getText());
break;
}
}
}
});
}
}
十五、RadioGroup
1、基本介绍
- RadioGroup 是 Android 中用于管理多个 RadioButton 组件的容器,它允许用户从一组选项中选择单一选项,确保同一时间只有一个 RadioButton 被选中
2、演示
(1)Activity Layout
- activity_radio_group_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".RadioGroupTestActivity">
<RadioGroup
android:id="@+id/rg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RadioButton
android:id="@+id/rb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选项 1" />
<RadioButton
android:id="@+id/rb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选项 2" />
<RadioButton
android:id="@+id/rb3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选项 3" />
</RadioGroup>
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
- RadioGroupTestActivity.java
package com.my.otherlayout;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.RadioButton;
import android.widget.RadioGroup;
public class RadioGroupTestActivity extends AppCompatActivity {
public static final String TAG = RadioGroupTestActivity.class.getSimpleName();
private RadioGroup rg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio_group_test);
rg = findViewById(R.id.rg);
rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton rb = findViewById(checkedId);
Log.i(TAG, "------------------------------ 选中了:" + rb.getText());
}
});
}
}
更多推荐
所有评论(0)