Android UI控件及布局
Android UI控件及布局
学习目标
1、掌握常用布局的特点和使用方法
2、掌握常用控件的功能和使用方法
3、熟悉自定义控件的实现和使用方法
4、掌握ListView的使用方法
5、掌握Fragment的使用方法
控件
1.TextView 主要用于界面上显示一段文本信息
android:gravity 来指定文字的对齐方式
android:textSize 来指定文字的大小
android:textColor 来指定文字的颜色
2.Button 按键按钮用于点击事件
android:textAllCaps="false" 禁用所有英文大小写转换
setOnClickListener 设置监听
3.EditText 允许用户在控件里输入和编辑内容
EditText editText = findViewById(R.id.edit_text)
editText.getText().toString()
//以上从编辑框中获取输入的内容
4.ImageView 图片展示控件
ImageView imageView = findViewById(R.id.image_view);
imageView.setImageResource(R.drawable.img_2);
//重新设置图片的资源地址
5.ProgressBar 进度条
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
progressBar.setVisibility(View.VISIBLE) //设置属性可见
progressBar.setVisibility(View.GONE) //设置属性不可见
ProgressBar progressBar = findViewById(R.id.progress_bar);
progressBar.setProgress(progressBar.getProgress() + 10);
//设置进度条的进度+10
6.AlertDialog 当前页面弹出一个对话框
AlertDialog.Builder 创建 AlertDialog的实例 设置内容是否可取消等属性
7.ProgressDialog 进度条对话框
setCancelable()中传入了false的话,表示不能通过Back取消掉,当数据加载完必须调用dismiss()方法关闭对话框
四种基本布局
1.线性布局LinearLayout
android:orientation 可以设置排列的方向(竖直vertical,水平horizontal )
android:layout_weight 允许使用比例方式来指定控件的大小
android:layout_gravity 用于指定控件在布局中的对齐方式
2.相对布局RelativeLayout
android:layout_alignParentLeft
android:layout_alignParentRight
android:layout_alignParentTop
android:layout_centerInParent
android:layout_alignParentBottom
以上的针对布局的左右上中下
android:layout_above="@id/relative_button3"
android:layout_below="@id/relative_button3"
android:layout_toLeftOf="@id/relative_button3"
android:layout_toRightOf="@id/relative_button3"
以上的相对与一个按钮的上下左右布局
3.帧布局FrameLayout
4.百分比布局
百分比布局,属于新增布局,需要增加依赖库
引入布局
1.新建布局文件title.xml(线性布局的LinearLayout)
2.在加载的文件中使用include进行引入子布局
<include layout="@layout/title"/>
创建自定义控件
1.新建java 类继承LinearLayout ,重写构造函数,通过LayoutInflater的from()方法可以构建LayoutInflater对象,调用inflate()方法动态加载一个布局文件
2.布局文件修改
最常/难用的控件--ListView
1.ListView简单用法
在布局的xml中增加<ListView>标签
代码中处理使用ArrayAdapter适配器实现
android.R.layout.simple_list_item_1
是安卓内部布局文件,作为ListView子布局的id
2.定制ListView界面
public class MainActivity5 extends BaseActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainfive);
initFruits();
FruitAdapter adapter = new FruitAdapter(MainActivity5.this, R.layout.fruit_item, fruitList);
ListView listView = findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
public void initFruits() {
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 pear = new Fruit("pear", R.drawable.pear);
fruitList.add(pear);
}
}
}
public class FruitAdapter extends ArrayAdapter<Fruit> {
private int resourceId;
public FruitAdapter(Context context, int textViewResourceId, List<Fruit> objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);
View view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
ImageView fruitImage = view.findViewById(R.id.fruit_image);
TextView fruitName = view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
return view;
}
}
3.优化ListView运行效率
@Override
public View getView(int position, View convertView, 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 = view.findViewById(R.id.fruit_image);
viewHolder.fruitName = view.findViewById(R.id.fruit_name);
view.setTag(viewHolder);//将ViewHolder储存在View中
}else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();//重新获取ViewHolder
}
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitName.setText(fruit.getName());
return view;
}
class ViewHolder{
ImageView fruitImage;
TextView fruitName;
}
4.ListView点击事件
setOnItemClickListener方法为ListView注册一个监听器
用户点击ListView中任何一个子项会回调onItemClick()
通过position参数判断出用户点击的是哪个子项,获取相应的水果
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainfive);
initFruits();
FruitAdapter adapter = new FruitAdapter(MainActivity5.this, R.layout.fruit_item, fruitList);
ListView listView = findViewById(R.id.list_view);
listView.setAdapter(adapter);
listView.setOnItemClickListener((parent, view, position, id) -> {
Fruit fruit = fruitList.get(position);
Toast.makeText(MainActivity5.this,fruit.getName(),Toast.LENGTH_SHORT).show();
});
}
强大的滚动控件---RecyclerView
1.RecyclerView基本用法
app/build.gradle导入依赖
implementation 'androidx.recyclerview:recyclerview:1.2.1'
修改布局文件
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
新建适配类继承RecyclerView.Adapter,指定泛型FruitAdapter.ViewHolder
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
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);
ViewHolder holder = new ViewHolder(view);
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();
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view) {
super(view);
fruitImage = view.findViewById(R.id.fruit_image);
fruitName = view.findViewById(R.id.fruit_name);
}
}
}
2.入口函数
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
//初始化数据
initFruits();
//获取滚动视图
RecyclerView recyclerView = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//让布局横行排列
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//设置视图的布局管理
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter = new FruitAdapter(fruitList);
//设置视图的适配器
recyclerView.setAdapter(adapter);
}
public void initFruits() {
for (int i = 0; i < 6; 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 pear = new Fruit("pear", R.drawable.pear);
fruitList.add(pear);
}
}
}
3.带点击处理的
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
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);
ViewHolder holder = new ViewHolder(view);
holder.fruitView.setOnClickListener(v ->
Toast.makeText(v.getContext(),"you clicked view "+ mFruitList.get(holder.getBindingAdapterPosition()).getName(),Toast.LENGTH_SHORT).show());
holder.fruitImage.setOnClickListener(v ->
Toast.makeText(v.getContext(),"you clicked image "+ mFruitList.get(holder.getBindingAdapterPosition()).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();
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView fruitImage;
TextView fruitName;
View fruitView;
public ViewHolder(View view) {
super(view);
fruitView = view;
fruitImage = view.findViewById(R.id.fruit_image);
fruitName = view.findViewById(R.id.fruit_name);
}
}
}
编写界面的最佳实践
1.制作.9图片
选择图片,右击选择create 9-path file选项
小黑点进行绘制边缘,shift拖动擦除
1:黑色条位置向下覆盖的区域表示图片横向拉伸时,只拉伸该区域
2:黑色条位置向右覆盖的区域表示图片纵向拉伸时,只拉伸该区域
3:黑色条位置向上覆盖的区域表示图片纵向显示内容的区域(在手机上主要是文字区域)
4:黑色条位置向左覆盖的区域表示图片横向显示内容的区域(在手机上主要是文字区域)
制作完成后,删除之前的message.png,保留message.9.png
<?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"
android:background="@drawable/message">
</LinearLayout>
注意点:xml中名称是不带.9的,还是之前的message
2.编写聊天界面
2.1写主界面的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"
android:background="#77F8A9A9"
android:padding="10dp"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<EditText
android:id="@+id/input_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Type somrthing here"
android:maxLines="2" />
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send" />
</LinearLayout>
</LinearLayout>
2.2写msg_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"
android:orientation="vertical">
<LinearLayout
android:id="@+id/left_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/message"
android:layout_gravity="left"
android:orientation="vertical">
<TextView
android:id="@+id/left_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:textColor="#fff" />
</LinearLayout>
<LinearLayout
android:id="@+id/right_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/message"
android:layout_gravity="right"
android:orientation="vertical">
<TextView
android:id="@+id/right_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center" />
</LinearLayout>
</LinearLayout>
注意点:这里的左右布局采用的是layout_gravity(布局问题一定注意,影响显示,或者不展示之类的)
android:gravity 是设置该view里面的内容相对于该view的位置, 例如设置button里面的text相对于view的靠左,居中等位置
android:layout_gravity 是用来设置该view相对与父view的位置, 例如设置button在layout里面的相对位置:屏幕居中,水平居中等
2.3新建Msg实体类
package com.example.uibestpractice;
public class Msg {
public static final int RECIVED_TYPE = 0;
public static final int SEND_TYPE = 1;
private int type;
private String content;
public int getType() {
return type;
}
public String getContent() {
return content;
}
public Msg(int type, String content) {
this.type = type;
this.content = content;
}
}
2.4新建MsgAdpter
public class MsgAdpter extends RecyclerView.Adapter<MsgAdpter.ViewHolder> {
private List<Msg> mMsgList;
public MsgAdpter(List<Msg> msgList) {
mMsgList = msgList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Msg msg = mMsgList.get(position);
if(msg.getType() == Msg.RECIVED_TYPE){
holder.leftMsg.setText(msg.getContent());
holder.leftLayout.setVisibility(View.VISIBLE);
holder.rightLayout.setVisibility(View.GONE);
}else if(msg.getType() == Msg.SEND_TYPE){
holder.rightMsg.setText(msg.getContent());
holder.rightLayout.setVisibility(View.VISIBLE);
holder.leftLayout.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return mMsgList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
LinearLayout leftLayout;
LinearLayout rightLayout;
TextView leftMsg;
TextView rightMsg;
public ViewHolder(View view) {
super(view);
leftLayout = view.findViewById(R.id.left_layout);
rightLayout = view.findViewById(R.id.right_layout);
leftMsg = view.findViewById(R.id.left_msg);
rightMsg = view.findViewById(R.id.right_msg);
}
}
}
2.5修改入口Activity
public class MainActivity extends AppCompatActivity {
private List<Msg> mMsgList = new ArrayList<>();
private MsgAdpter adapter;
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initMsg();
adapter = new MsgAdpter(mMsgList);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
findViewById(R.id.send).setOnClickListener(view -> {
EditText input = findViewById(R.id.input_text);
if (!"".equals(input.getText().toString())) {
mMsgList.add(new Msg(Msg.SEND_TYPE, input.getText().toString()));
adapter.notifyItemInserted(mMsgList.size() - 1);
recyclerView.scrollToPosition(mMsgList.size() - 1);
input.setText("");
}
if(mMsgList.size() == 3){
mMsgList.add(new Msg(Msg.RECIVED_TYPE,"What's your name?"));
adapter.notifyItemInserted(mMsgList.size()-1);
recyclerView.scrollToPosition(mMsgList.size()-1);
}
if(mMsgList.size() == 5){
mMsgList.add(new Msg(Msg.RECIVED_TYPE,"Nice to meet you,Bye!"));
adapter.notifyItemInserted(mMsgList.size()-1);
recyclerView.scrollToPosition(mMsgList.size()-1);
}
if(mMsgList.size() == 6){
mMsgList.add(new Msg(Msg.SEND_TYPE,"Bye"));
adapter.notifyItemInserted(mMsgList.size()-1);
recyclerView.scrollToPosition(mMsgList.size()-1);
}
});
}
private void initMsg() {
Msg msg1 = new Msg(Msg.RECIVED_TYPE, "你好!");
mMsgList.add(msg1);
Msg msg2 = new Msg(Msg.SEND_TYPE, "你好呀!");
mMsgList.add(msg2);
}
}
聊天项目
1. 横向布局管理创建 new LinearLayoutManager(this)
2. RecyclerView设置布局管理、设置适配器
3. MsgAdpter适配器继承RecyclerView.Adapter,其中onBindViewHolder函数会根据List大小循环调用绑定
本文来自博客园,作者:阿寳同學Zybao,转载请注明原文链接:https://www.cnblogs.com/zybao/p/16877104.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步