Android的UI开发

一.常用控件

android:layout_Width和android:layout_height指定空间的宽度和高度.可选值有:
match_parent:表示让当前控件的大小和父布局的大小一样,由父布局来决定当前控件的大小.
wrap_content:表示当前控件的大小能刚好包含住里面的内容,由空间内容决定当前控件的大小.
fill_parent:match_parent意义相同(存在少部分版本问题)

1.TextView

属性

概括

备注

text

显示的内容

gravity

文字对齐方式

top,bottom,left,right,center等参数

textSize

字体大小

sp做单位

textSize

字体颜色

2.Button

系统会自动将字体转为大写

属性

概括

备注

textAllCape

禁用默认转化

true,false参数

3.EditText

该组件允许用户在控件里输入和编辑内容,并可以在程序中对这些内容进行处理.

属性

概括

备注

hint

灰底提示信息

maxLines

指定提示信息的最大长度

1~x行

4.ImageView

该组件用于在界面上展示的一个控件,它可以yu让我们的程序界面变的更加丰富.

属性

概括

备注

src

定义指定的图片

layout_width

指定图片宽度

layout_height

指定图片高度

5.ProgressBar

该控件用于在界面上显示一个进度条,表示程序正在加载一些数据

属性

概括

备注

visibility

可见属性

visible,invisible,gone参数.(visible是默认可见的,invisble不可见,但占据空间,gone不可见,不占据空间)

style

控制进度条样式

max

设置最大值

6.AlertDialog

AlertDialog可以在当前的界面弹出对话框,至于所有界面之上,屏蔽掉其他控件的交互能力
实现View.onClickListener接口重写onclick方法

@Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.button:
            //创建AlertDialog实例,为对话框设置标题,内容,是否可用Back键关闭对话框等属性.
                AlertDialog.Builder dialog=new AlertDialog.Builder(MainActivity.this);
                dialog.setTitle("This is Dialog");
                dialog.setMessage("Something important.");
                dialog.setCancelable(false);
                //为对话框设置确定按钮的点击事件
                dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                });
                //设置取消按钮的点击事件
                dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int whick) {
                    }
                });
                //将对话框显示出来
                dialog.show();
                break;
            default:
                break;
        }
    }

7.ProgressDialog

该控件与AlertDialog有些类似,不同点在于ProgressDialog在对话框中显示一个进度条

二.四种基本布局

1.线性布局(LinearLayout)

属性

概括

备注

orientation

结构方向

vertical(垂直),horizontal(水平).排列方式是horizontal时,内部的空间就绝对不能将宽度指定为match_parent.排列方式是vertical时,内部的空间就绝对不能将高度指定为match_parent.

layout_gravity

对齐方式

top,center_vertical,buttom

layout_weight

比例控制控件大小

2.相对布局(RelativeLayout)

属性

概括

备注

layout_alignParentLeft

左对齐

true/false

layout_alignParentRight

右对齐

true/false

layout_alignParentTop

顶端

true/false

layout_alignParentBottom

底部

trua/false

layout_centerInParent

剧中

true/false

layout_above

相对于其他控件位置

layout_above

置于控件上方

layout_below

置于控件下方

layout_toLeftOf

置于控件左侧

layout_toRightOf

置于控件右侧

layout_alignLeft

一个控件的左边缘和另一个控件的左边缘对齐

layout_alignRight

一个控件的右边缘和另一个控件的右边缘对齐

layout_alignTop

一个控件的上边缘和另一个控件的上边缘对齐

layout_alignBottom

一个控件的下边缘和另一个控件的下边缘对齐

3.帧布局(FrameLayout)

所有控件默认都摆放在布局的左上角,可以用layout_gravity来进行定位.

4.百分比布局(PercentFrameLayout)

百分比布局只为FrameLayout和RelativeLayout进行功能扩展,LinearLayout本身已经支持比例调控

属性

概括

备注

layout_widthPercent

宽度

x%

layout_heightPercent

高度

y%

5.ListView

1.简单用法

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity">

   <ListView
       android:id="@+id/list_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>
</LinearLayout>

MainActivity.class
Arraydapter适配器,参数1:当前上下文,参数2:ListView子项布局的id,参数3:要是适配的数据.
setAdapter(),将构建好的适配器对象传递进去,使ListView和数据之间的关联就建立完成.

public class MainActivity extends AppCompatActivity {
    private String[]data={"Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry," +
            "Mango","Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,data);
        ListView listView=(ListView) findViewById(R.id.list_view);
        listView.setAdapter(adapter);
    }
}
2.定制ListView的界面

定义一个实体类,作为ListView适配器的适配类型.

public class Fruit{
private String name;
private int imageId;

public Fruit(String name,int imageId){
this.name=name;
this.imageId=imageId;
}
public String getName(){
return name;
}
public int getImageId(){
return imageId;
}
}

fruit_item.xml指定自定义的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/fruit_image"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
    <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类
FruitAdaoter重写父类的一组构造函数,用于将上下文,ListView子项布局的id和数据都传递进来,重写getView()方法,让每一个子项被滚动到屏幕内的时候会被调用.
LayoutInflaterinflate()方法.参数1:布局文件的资源Id;参数2:(1)当attachToRoot为true时,该方法返回的view对象会自动被添加到root中作为root的一个子控件;
(2).当attachToRoot为false时,该方法返回的view只会获得root的布局属性
如果root为null,则第三个参数无效,且生产的view的getLayoutParams()会返回空,也就是 view不会有布局属性.参数3:true/false

public class FruitAdapter extends ArrayAdapter<Fruit> {
    private int resourceId;
    public FruitAdapter(@NonNull Context context, int textViewResourceId, @NonNull List<Fruit> objects) {
        super(context, textViewResourceId, objects);
        resourceId=textViewResourceId;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Fruit fruit=getItem(position);//获取当前项的Fruit实例
        //为子项加载传入的布局
        View view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
        ImageView fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
        TextView fruitName=(TextView) view.findViewById(R.id.fruit_name);
        fruitImage.setImageResource(fruit.getImageId());
        fruitName.setText(fruit.getName());
        return view;
    }
}

MainActivity.class
用于初始化水果数据,进行对应水果名字和图片的传入

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);
        initFruits();//初始化水果数据
        FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
        ListView listView=(ListView) findViewById(R.id.list_view);
        listView.setAdapter(adapter);
    }
    private void initFruits(){
        for(int i=0;i<2;i++){
            Fruit apple=new Fruit("Apple",R.drawable.abc_vector_test);
            fruitList.add(apple);
            ...
        }
    }
}
3.点击事件
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();//初始化水果数据
        FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
        ListView listView=(ListView) findViewById(R.id.list_view);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @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();
            }
        });
    }

6.滚动控件(RecyclerView)

1.RecyclerView基本用法

在app/build.gradle文件,dependencies闭包添加
implementation 'android.recyclerview:recyclerview:1.0.2' 在activity_main.xml

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_View"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

为RecyclerView准备一个适配器

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    private List<Fruit> mFruitList;

    @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=(ImageView) view.findViewById(R.id.fruit_image);
            fruitName=(TextView) view.findViewById(R.id.fruit_name);
        }
    }
    public FruitAdapter(List<Fruit> fruitList){
        mFruitList=fruitList;
    }
}
使用RecycleView

```java
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);
        initFruits();
        RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recycler_View);
        LinearLayoutManager layoutManager=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        FruitAdapter adapter=new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }
    private void initFruits(){
        for(int i=0;i<2;i++){
            Fruit apple=new Fruit("Apple",R.drawable.abc_vector_test);
            fruitList.add(apple);
       .......

        }
}
}
2.实现横向滚动和瀑布流布局

横向滚动
修改fruit_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/fruit_image"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_gravity="center_horizontal"/>
    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"/>
</LinearLayout>

在MainActivity中

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        RecyclerView 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);
    }

瀑布流布局
fruit_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:orientation="vertical">

MainActivity.class
StaggeredGridLayoutManager的构造函数接收两个参数,参数1:用于指定布局的列数.参数2:指定布局的排列方式,StaggeredGridLayoutManager.VERTICAL是布局纵向排列.
getRandomLengthName()是为了让排列达到高度不一的瀑布效果.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recycler_View);
//        LinearLayoutManager layoutManager=new LinearLayoutManager(this);
//        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        StaggeredGridLayoutManager layoutManager=new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        FruitAdapter adapter=new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }
    ---------------------------------------
    private void initFruits(){
        for(int i=0;i<2;i++){
            Fruit apple=new Fruit(getRandomLengthName("Apple"),R.drawable.abc_vector_test);
            fruitList.add(apple);
            ......
     ------------------------------------
     private String getRandomLengthName(String name){
    Random random=new Random();
    int length= random.nextInt(20)+1;
    StringBuilder builder=new StringBuilder();
    for (int i = 0; i <length ; i++) {
        builder.append(name);
    }
    return builder.toString();
}
3.RecyclerView的点击事件

RecyclerView没有提供注册监视器的方法,需要自己注册.

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    private List<Fruit> mFruitList;
    static class ViewHolder extends RecyclerView.ViewHolder{
        ImageView fruitImage;
        TextView fruitName;
        View fruitView;
        public ViewHolder(View view){
            super(view);
            fruitView=view;
            fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
            fruitName=(TextView) view.findViewById(R.id.fruit_name);
        }
    }
    @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 view) {
               int position=holder.getAdapterPosition();
               Fruit fruit=mFruitList.get(position);
               Toast.makeText(view.getContext(), "you clicked view"+fruit.getName(), Toast.LENGTH_SHORT).show();
           }
       });
        holder.fruitImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position= holder.getAdapterPosition();
                Fruit fruit=mFruitList.get(position);
                Toast.makeText(view.getContext(),"you clicked image"+fruit.getName(),Toast.LENGTH_SHORT).show();
            }
        });
        return holder;
    }
    .........