第三章UI

若如初见. 提交于 2020-02-24 14:21:22

常用控件

  • textview
    match_parent:和父局大小一样
    wrap_content:由内容决定大小
    文字对齐方式:
android:gravity="center"
  • button
    默认字母全部大写
    禁用大写:
android:textAllCaps="false"
  • edittext
    提示性文本:
android:hint="请输入"

解决内容过大问题:

android:maxLines="2"
  • imageview
  • progressbar
    圆形进度条
 public void onClick(View view) {
                if(progressBar.getVisibility()==View.GONE){
                    progressBar.setVisibility(View.VISIBLE);
                }else {
                    progressBar.setVisibility(View.GONE);
                }
            }

长形进度条

        style="?android:attr/progressBarStyleHorizontal"
        android:max="100"

AlertDialog

弹出对话框

public void onClick(View view) {
                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
                dialog.setTitle("注意");
                dialog.setMessage("重要");
                dialog.setCancelable(false);
                dialog.setPositiveButton("ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                    }
                });
                dialog.setNegativeButton("cancle", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
                dialog.show();
            }

在这里插入图片描述

ProgressDialog

当前操作比较耗时,让用户耐心等待

public void onClick(View view) {
                ProgressDialog progressDialog=new ProgressDialog(MainActivity.this);
                progressDialog.setTitle("注意");
                progressDialog.setMessage("Loading.....");
                progressDialog.setCancelable(true);
                progressDialog.show();
            }

在这里插入图片描述
如果是progressDialog.setCancelable(false);则表示progressdialog是不能通过back键取消

四种布局

  • 线性布局
    垂直vertical 水平 horizontal
  • 相对布局
  • 帧布局
  • 百分比布局

自定义控件

在这里插入图片描述

引入布局

自定义xml后,在需要使用的xml中:

<include layout="@layout/title"/>
创建自定义控件

新建类继承自LinearLayout

public class titlelayout extends LinearLayout {

    public titlelayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.title,this);
    }
}

LayoutInflater.from()可以构建出一个LayoutInflater对象,然后调用inflate()方法可以动态加载一个布局,第一个参数是要加载布局的第二个是给加载好的布局再添加一个父布局,

在需要使用的xml中添加如下:

<com.example.lydia.myapplication.titlelayout
        android:layout_height="match_parent"
        android:layout_width="match_parent" />

注:这种使用方式和引入布局效果是一样的
在类中定义控件的点击方式:

public class titlelayout extends LinearLayout {

    public titlelayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.title,this);
        Button titleBack=findViewById(R.id.button1);
        Button titleEdit=findViewById(R.id.button2);
        titleBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                ((Activity)getContext()).finish();
            }
        });
        titleEdit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getContext(),"edit",Toast.LENGTH_SHORT).show();
            }
        });

    }
}

最难用的控件ListView

  • 基本使用:
 <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
private String[] data={"apple","banana","orange","pear","apple","banana","orange","pear","apple","banana","orange","pear",
            "apple","banana","orange","pear","apple","banana","orange","pear"};
    @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=findViewById(R.id.listview);
        listView.setAdapter(adapter);
    }

在这里插入图片描述

  • 定制ListView界面
    LayoutInflater.from()可以构建出一个LayoutInflater对象,然后调用inflate()方法可以动态加载一个布局,第一个参数是要加载布局的第二个是给加载好的布局再添加一个父布局,第三个参数指定生成false,表示只让我们在父布局中声明的layout失效,但不为这个view添加父布局,因为一旦有了父布局后,他就再也不能添加到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;
    }
}

为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="wrap_content">
    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="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

package com.example.lydia.listview;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
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 java.util.List;

public class FruitAdapter extends ArrayAdapter<Fruit> {
    private int resourceID;

    public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
        super(context, resource, objects);
        resourceID=resource;
    }

    @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=view.findViewById(R.id.fruit_image);
        TextView fruitname=view.findViewById(R.id.fruit_name);
        fruitImage.setImageResource(fruit.getImageID());
        fruitname.setText(fruit.getName());
        return view;
    }
}

getView():每个子项在被滚动到屏幕内的时候会被调用
MainActivity:

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=findViewById(R.id.listview);
        listView.setAdapter(adapter);
    }
    private void initfruits() {
        for(int i=0;i<3;i++){
            Fruit apple=new Fruit("Apple",R.drawable.buddy_1_mb5ucom);
            Log.d("TAG","apple");
            fruitList.add(apple);
            Fruit orange=new Fruit("orange",R.drawable.buddy_2_mb5ucom);
            Log.d("TAG","orange");
            fruitList.add(orange);
            Fruit pear=new Fruit("pear",R.drawable.buddy_3_mb5ucom);
            fruitList.add(pear);
            Fruit cherry=new Fruit("cherry",R.drawable.buddy_4_mb5ucom);
            fruitList.add(cherry);
            Fruit mango=new Fruit("mango",R.drawable.buddy_5_mb5ucom);
            fruitList.add(mango);
        }
    }

}

在这里插入图片描述

提升ListView效率

  • 使用getview()中的convertView参数,对之前加载好的布局进行缓存
        View view;
        if(convertView==null){
            view= LayoutInflater.from(getContext()).inflate(resourceID,parent,false);
        }
        else{
            view=convertView;
        }
  • 新增内部类ViewHolder,用来对控件的实例进行缓存
 public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Fruit fruit=getItem(position);//获取当前fruit实例
        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.fruitName.setText(fruit.getName());
        viewHolder.fruitImage.setImageResource(fruit.getImageID());
        return view;
    }
    class ViewHolder{
        ImageView fruitImage;
        TextView fruitName;
    }

RecyclerView的基本用法

打开app/build.gradle文件,添加

 implementation 'com.android.support:recyclerview-v7:+'

activity_main.xml

<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">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>

</LinearLayout>

准备一个适配器

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{
    private List<Fruit> mFruitlist;
    static  class ViewHolder extends RecyclerView.ViewHolder{
        ImageView fruitImage;
        TextView fruitName;
        public ViewHolder(@NonNull View itemView) {//这里的view通常是RecyclerView的最外层布局
            super(itemView);
            fruitImage=itemView.findViewById(R.id.fruit_image);
            fruitName=itemView.findViewById(R.id.fruit_name);
        }
    }
    public FruitAdapter(List<Fruit> mFruitlist) {//把需要展示的数据源传进来
        this.mFruitlist = mFruitlist;
    }

    @NonNull
    @Override//创造ViewHolder实例,将fruit_item加载进来,然后创建一个ViewHolder实例
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fruit_item,viewGroup,false);
        ViewHolder viewHolder=new ViewHolder(view);
        return viewHolder;
    }

    @Override//对recyclerview子项进行复制
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        Fruit fruit=mFruitlist.get(i);
        viewHolder.fruitImage.setImageResource(fruit.getImageID());
        viewHolder.fruitName.setText(fruit.getName());
    }

    @Override//告诉recyclerview有多少子项
    public int getItemCount() {
        return mFruitlist.size();
    }
}

MainActivity

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=findViewById(R.id.recycler_view);
        //LinearLayoutManager用于指定RecyclerView的布局方式,可以实现和listview同样的效果
        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        FruitAdapter adapter=new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }

    private void initfruits() {
        for(int i=0;i<3;i++){
            Fruit apple=new Fruit("apple",R.mipmap.buddy_1_mb5ucom);
            fruitList.add(apple);
            Fruit banana=new Fruit("banana",R.mipmap.buddy_2_mb5ucom);
            fruitList.add(banana);
            Fruit orange=new Fruit("orange",R.mipmap.buddy_3_mb5ucom);
            fruitList.add(orange);
            Fruit pear=new Fruit("pear",R.mipmap.buddy_4_mb5ucom);
            fruitList.add(pear);
            Fruit grape=new Fruit("grape",R.mipmap.buddy_5_mb5ucom);
            fruitList.add(grape);
        }

    }

}

在这里插入图片描述

实现横向滚动和瀑布流布局

横向滚动

修改fruit_item

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

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="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_vertical"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"/>


</LinearLayout>

MainActivity中添加

linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

在这里插入图片描述

瀑布流

修改fruit_item

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

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="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="left"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"/>



修改MainActivity

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=findViewById(R.id.recycler_view);
        //3列,纵向排布
        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<3;i++){
            Fruit apple=new Fruit(getRandomLengthName("apple"),R.mipmap.buddy_1_mb5ucom);
            fruitList.add(apple);
            Fruit banana=new Fruit(getRandomLengthName("banana"),R.mipmap.buddy_2_mb5ucom);
            fruitList.add(banana);
            Fruit orange=new Fruit(getRandomLengthName("orange"),R.mipmap.buddy_3_mb5ucom);
            fruitList.add(orange);
            Fruit pear=new Fruit(getRandomLengthName("pear"),R.mipmap.buddy_4_mb5ucom);
            fruitList.add(pear);
            Fruit grape=new Fruit(getRandomLengthName("grape"),R.mipmap.buddy_5_mb5ucom);
            fruitList.add(grape);
        }
    }
    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();
    }

}

在这里插入图片描述

RecyclerView的点击事件

修改FruitAdapter代码
先修改ViewHolder,再添加fruitView来保存子项最外侧布局的实例,
这里分别为最外层布局和ImageView都注册了点击事件

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{
    private List<Fruit> mFruitlist;
    static  class ViewHolder extends RecyclerView.ViewHolder{
        View fruitView;
        ImageView fruitImage;
        TextView fruitName;
        public ViewHolder(@NonNull View itemView) {//这里的view通常是RecyclerView的最外层布局
            super(itemView);
            fruitView=itemView;
            fruitImage=itemView.findViewById(R.id.fruit_image);
            fruitName=itemView.findViewById(R.id.fruit_name);
        }
    }
    public FruitAdapter(List<Fruit> mFruitlist) {//把需要展示的数据源传进来
        this.mFruitlist = mFruitlist;
    }

    @NonNull
    @Override//创造ViewHolder实例,将fruit_item加载进来,然后创建一个ViewHolder实例
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fruit_item,viewGroup,false);
        final  ViewHolder viewHolder=new ViewHolder(view);
        viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position=viewHolder.getAdapterPosition();
                Fruit fruit=mFruitlist.get(position);
                Toast.makeText(view.getContext(),"click"+fruit.getName(),Toast.LENGTH_SHORT).show();
            }
        });
        viewHolder.fruitImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position=viewHolder.getAdapterPosition();
                Fruit fruit=mFruitlist.get(position);
                Toast.makeText(view.getContext(),"click"+fruit.getName(),Toast.LENGTH_SHORT).show();
            }
        });

        return viewHolder;
    }

    @Override//对recyclerview子项进行复制
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        Fruit fruit=mFruitlist.get(i);
        viewHolder.fruitImage.setImageResource(fruit.getImageID());
        viewHolder.fruitName.setText(fruit.getName());
    }

    @Override//告诉recyclerview有多少子项
    public int getItemCount() {
        return mFruitlist.size();
    }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!