Android第一行代码——第三章控件和布局

本章主要介绍常用的控件和基本的布局方法

- 常用控件

1. TextView

在界面上显示一段文本信息
 <TextView
        android:id="@+id/textView_Test"		//设置唯一标识符
        android:layout_width="wrap_content"		// 宽度
        android:layout_height="wrap_content"	//高度	
        android:gravity="center"				//文字对齐方式
        android:text="Hello World!"				//指定TextVIiew显示的内容
        android:textSize="24sp"					//指定文字大小	
        android:textColor="#00ff00"				//指定文字颜色
        />

2. Button

在界面上显示一个按钮
<Button
        android:id="@+id/button_Test"			//设置唯一标识符
        android:layout_width="match_parent"		
        android:layout_height="wrap_content"
        android:text="Hello"				//指定Button显示的内容
        android:textAllCaps="false"			//指定英文是否大写,默认是大写
        />

3.EditText

可编辑的文本,允许用户在控件里输入和编辑
<EditText
        android:id="@+id/EditText_Test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Type something here"		//显示提示性文字
        android:maxLines="2"/>					//指定最大行数

4.ImageView

在界面上显示图片
<ImageView
        android:id="@+id/imageView_Test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ccc"/>				//为ImaheVIew指定图片

5.ProgressBar

在界面上显示一个进度条
<ProgressBar
        android:id="@+id/progressBar_Test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleHorizontal"  //默认是圆形进度条,这个属性可改为水平进度条
        android:max="100"		//给进度条设置最大值
        />

6.AlertDialog

在当前界面弹出一个对话框,不同于上面的,这个是在程序中写的
	AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
    dialog.setTitle("This is a dialog");		//设置标题
    dialog.setMessage("Message");				//设置内容
    dialog.setCancelable(false);        //设置不可用Back键关闭对话框
   	//设置确定按钮的点击事件
    dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    
    
     	@Override
     	public void onClick(DialogInterface dialogInterface, int i) {
    
    

         }
    });
    //设置取消按钮的点击事件
    dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    
    
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
    
    

        }
    });
    dialog.shou();			

7.ProgressDialog

在当前界面弹出一个有进度条的对话框,也是在程序中完成
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setTitle("This is a ProgressDialog");
        progressDialog.setMessage("Loading...");
        progressDialog.setCancelable(false);
        progressDialog.show();

- 常用布局

1.LinearLayout

线性布局,将他所包含的控件在线性方向上依次排列
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"			//指定排列方式,水平|垂直
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button_Test"
        android:layout_width="0dp"				//使用比例控制大小时,由于排列是水平的,layout_width属性将不起作用,写成这样是一种规范
        android:layout_weight="1"				//使用比例来控制控件大小
        android:layout_gravity="center"			//指定对齐方式
        android:layout_height="wrap_content"
        android:text="Hello"
        android:textAllCaps="false"
        />
    <EditText
        android:id="@+id/EditText_Test"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:hint="Type something here"
        android:maxLines="2"/>

</LinearLayout>

2.RelativeLayout

相对布局,可通过相对于父布局或相对于其他控件来约束控件位置
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    //layout_alignParentLeft,layout_alignParentTop,layout_alignParentRight,
    //layout_alignParentButton,layout_centerInParent,相对于父布局
    <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="Hello"
        android:textAllCaps="false"
        />
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:text="Hello"
        android:textAllCaps="false"
        />
    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Hello"
        android:textAllCaps="false"
        />
 	 //  layout_toLeftOf,layout_toRightOf,layout_above,layout_below
  	//相对于其他布局   
    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/button3"
        android:layout_above="@+id/button3"
        android:text="Hello"
        android:textAllCaps="false"
        />
    <Button
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/button3"
        android:layout_below="@+id/button3"
        android:text="Hello"
        android:textAllCaps="false"
        />
        //layout_alignLeft,layout_alignRight,layout_alignTop,layout_alignBottom
        //与其他控件边缘对齐
    <Button
        android:id="@+id/button6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/button3"
        android:layout_below="@+id/button3"
        android:text="Hello"
        android:textAllCaps="false"
        />

</RelativeLayout>

3.FrameLayout

帧布局,默认所有的控件都摆放在布局的左上角
<?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:id="@+id/textView_Test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Hello World!"
        android:textSize="24sp"
        android:textColor="#00ff00"
        />
    <EditText
        android:id="@+id/EditText_Test"
        android:layout_gravity="bottom"			//也可用此属性来指定对齐方式
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Type something here"
        android:maxLines="2"/>

</FrameLayout>

4.PercentFrameLayout

百分比布局,FrameLayout的拓展,使用之前要先导包

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<androidx.percentlayout.widget.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <Button
        android:id="@+id/button_Test"
        android:layout_width="match_parent"		//百分比布局中这两个属性不起作用
        android:layout_height="wrap_content"
        android:layout_gravity="left|top"
        app:layout_widthPercent ="50%"			//指定宽度为布局的50%
        app:layout_heightPercent="50%"			//指定高度为布局的50%
        android:text="Hello"
        android:textAllCaps="false"
        />
    <Button
        android:id="@+id/button_Test2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="right|top"
        app:layout_widthPercent ="30%"
        app:layout_heightPercent="30%"
        android:text="Hello"
        android:textAllCaps="false"
        />

</androidx.percentlayout.widget.PercentFrameLayout>

4.PercentRelativeLayout

百分比布局,PerentLayout的拓展,使用之前要先导包(和上面的是一个包),两个布局的方法都可用
<?xml version="1.0" encoding="utf-8"?>
<androidx.percentlayout.widget.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        app:layout_widthPercent="50%"
        app:layout_heightPercent="50%"
        android:text="Hello"
        android:textAllCaps="false"
        />
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        app:layout_widthPercent="50%"
        app:layout_heightPercent="50%"
        android:text="Hello"
        android:textAllCaps="false"
        />

</androidx.percentlayout.widget.PercentRelativeLayout>

4.ConstraintLayout

约束布局,可参看约束布局
效果:在这里插入图片描述
<?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="@drawable/aaa"
    tools:context=".MainActivity">
    <androidx.constraintlayout.widget.Guideline    	//添加一个Guideline虚拟线
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"				//虚拟线的方向
        app:layout_constraintGuide_percent="0.4" />		//在屏幕的比例位置
    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="用户名"
        android:textSize="24sp"
        app:layout_constraintEnd_toStartOf="@id/guideline"		
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/password"
        app:layout_constraintVertical_chainStyle="packed"
         //改变纵向的chain风格,默认是spread,就是均匀分布,packed是聚合在一起,
        //还有一个属性是spread_inside,表示分布在两边
        app:layout_constraintVertical_bias="0.32"
        android:layout_marginEnd="5dp"			//距边缘的距离
        android:layout_marginRight="5dp" />
    <TextView
        android:id="@+id/password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="密码"
        android:textSize="24sp"
        app:layout_constraintEnd_toStartOf="@id/guideline"
        app:layout_constraintTop_toBottomOf="@id/username"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
       
        android:layout_marginEnd="5dp"
        android:layout_marginRight="5dp"

        />
    <EditText
        android:id="@+id/usernameEdit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:hint="输入用户名"
        app:layout_constraintBaseline_toBaselineOf="@id/username"	//使用基线约束的方式进行对齐操作
        app:layout_constraintStart_toEndOf="@id/guideline"/>
    <EditText
        android:id="@+id/passwordEdit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:hint="输入密码"
        app:layout_constraintBaseline_toBaselineOf="@id/password"
        app:layout_constraintStart_toEndOf="@id/guideline"/>
    <Button
        android:id="@+id/logon"
        android:text="注册"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        app:layout_constraintTop_toBottomOf="@id/password"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/login"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="0.4"

        />
    <Button
        android:id="@+id/login"
        android:text="登录"
        android:textSize="18sp"
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/password"
        app:layout_constraintStart_toEndOf="@id/logon"
        app:layout_constraintEnd_toEndOf="parent"
        />


</androidx.constraintlayout.widget.ConstraintLayout>

- 引入布局

通过 include layout="@layout/"将一个布局引入到当前布局
引入title.xml布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >
    <include layout="@layout/title"/>
 </LinearLayout>   

- 自定义控件

优点:复用性高,可以解决引入布局响应事件每次重写的问题

1.创建控件
//创建一个类继承自LinearLayout
public class TitleLayout extends LinearLayout {
    
    

    public TitleLayout(Context context, @Nullable AttributeSet attrs) {
    
    
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.title,this);  //动态加载布局
        Button button1 = (Button)findViewById(R.id.button_back);	//可设置点击事件

    }
}
2.引入控件
 <com.example.revise_3.TitleLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <include layout="@layout/title"/>

- ListView

1.主布局中引入LIstView
<?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">
<ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
</LinearLayout>
2.写子项布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/listView_imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/listView_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="24sp"
        />

</LinearLayout>
3.定义实体类,作为适配器的适配类型
package com.example.revise_3;

public class Simple {
    
    
    private String Name;
    private int imageId;

    public String getName() {
    
    
        return Name;
    }

    public int getImageId() {
    
    
        return imageId;
    }

    public Simple(String name, int imageId) {
    
    
        Name = name;
        this.imageId = imageId;
    }
}

4.写适配器类
package com.example.revise_3;

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;
//让这个类继承自ArrayAdapter
public class ListViewAdapt extends ArrayAdapter<Simple> {
    
    
    private int Resource;			//用于下面获取View
    public ListViewAdapt(@NonNull Context context, int resource, @NonNull List<Simple> objects) {
    
    
        super(context, resource, objects);
        Resource = resource;	//获取子项的resource
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    
    

        Simple simple = getItem(position);	//获取当前的simple实例
        View view;
        ViewHolder viewHolder;
        if(convertView==null){
    
    
            view = LayoutInflater.from(getContext()).inflate(Resource,parent,false);
            //得到当前的view实例
            viewHolder = new ViewHolder();
            viewHolder.imageView = (ImageView)view.findViewById(R.id.listView_imageView);
            viewHolder.textView = (TextView)view.findViewById(R.id.listView_textView);
            view.setTag(viewHolder);		//将viewHolder储存在view中
        }
        else{
    
    
            view = convertView;
            viewHolder = (ViewHolder)view.getTag();
        }

        viewHolder.imageView.setImageResource(simple.getImageId());
        viewHolder.textView.setText(simple.getName());
        return view;
    }
    class ViewHolder{
    
    		//用于优化
        ImageView imageView;
        TextView textView;
    }
}

5.把适配器实例传入LIstView
public class MainActivity extends AppCompatActivity {
    
    
    private List<Simple> list = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
       ...
        addlist();
        
        ListView listView = (ListView)findViewById(R.id.listView);
        ListViewAdapt adapt = new ListViewAdapt(MainActivity.this,R.layout.listview_item,list);
        listView.setAdapter(adapt);
        //设置点击事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    
    
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
    
    
                Toast.makeText(MainActivity.this,"you click"+i,Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void addlist() {
    
    
        String name;
        int id;
        for(int i = 0; i < 20;i++){
    
    
            name = "这是"+i+"个";
            id = R.mipmap.ic_launcher;
            Simple simple = new Simple(name,id);
            list.add(simple);
        }
    }

- RecyclerView

1.导包,在主布局中引入RecyclerView
<?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/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
2.写子项布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/listView_imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/listView_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="24sp"
        />

</LinearLayout>
3.定义实体类,作为适配器的适配类型
package com.example.revise_3;

public class Simple {
    
    
    private String Name;
    private int imageId;

    public String getName() {
    
    
        return Name;
    }

    public int getImageId() {
    
    
        return imageId;
    }

    public Simple(String name, int imageId) {
    
    
        Name = name;
        this.imageId = imageId;
    }
}

4.写适配器类
package com.example.revise_3;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class RecyclerviewAdapt extends RecyclerView.Adapter<RecyclerviewAdapt.ViewHolder> {
    
    
    private List<Simple> list = new ArrayList<>();
    
    class ViewHolder extends RecyclerView.ViewHolder{
    
    
        private ImageView imageView;
        private TextView textView;
        public ViewHolder(@NonNull View itemView) {
    
    
       	// itemView这个参数通常就是Recyclerview子项的最外层布局,可用于获取子项布局里控件的实例
            super(itemView);
            imageView = (ImageView)itemView.findViewById(R.id.listView_imageView);
            textView = (TextView)itemView.findViewById(R.id.listView_textView);

        }
    }
    //构造方法,传递数据
    public RecyclerviewAdapt(List<Simple> list){
    
    
        this.list = list;
    }

    @NonNull
    @Override
    //这个方法主要用于获取ViewHolder实例
    public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, int viewType) {
    
    
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item,parent,false);
        ViewHolder viewHolder = new ViewHolder(view);
        //注册点击事件
        viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View view) {
    
    
                Toast.makeText(view.getContext(),"you click",Toast.LENGTH_SHORT).show();
            }
        });
        return viewHolder;
    }
    //这个方法用于对子项数据进行赋值
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    
    
        Simple simple = list.get(position);
        holder.textView.setText(simple.getName());
        holder.imageView.setImageResource(simple.getImageId());
    }
	//这个方法用于获取一共有多少子项
    @Override
    public int getItemCount() {
    
    
        return list.size();
    }


}

5.传入适配器,指定布局方式
 private List<Simple> list = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
       ...
        addlist();
       
        RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
        // layoutManager 用于指定RecyclerView的布局方式
        //线性布局
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        //可调用setOrientation来指定布局的排列方向,默认是纵向
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        //网格布局,第一个参数是上下文,第二个参数是一行的数量
        GridLayoutManager layoutManager1 = new GridLayoutManager(this,4);
        //瀑布式布局,第一个参数是布局的列数,第二个参数是布局的排列方向,下面传入的表示纵向排列
        StaggeredGridLayoutManager layoutManager2 = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
        RecyclerviewAdapt adapt = new RecyclerviewAdapt(list);
        recyclerView.setAdapter(adapt);
        //recyclerView.setLayoutManager(layoutManager);
        recyclerView.setLayoutManager(layoutManager1);
    }

    private void addlist() {
    
    
        String name;
        int id;
        for(int i = 0; i < 20;i++){
    
    
            name = "这是"+i+"个";
            id = R.mipmap.ic_launcher;
            Simple simple = new Simple(name,id);
            list.add(simple);
        }
    }

编写界面的最佳实践

课后demo

猜你喜欢

转载自blog.csdn.net/haazzz/article/details/108544934