第3章 UI开发的点点滴滴

作者: 追梦小乐 | 来源:发表于2018-04-15 01:06 被阅读323次

    本系列学习笔记第3章

    前言

    打算把android基本知识点写一个系列,旨在把android基础书,例如《Android 第一行代码 第2版》、《爱上android》、《疯狂android讲义》等书的一些知识点记录一下,会持续更新内容,为了方便自己复习,也希望可以帮助到大家!

    1、TextView

        <TextView
            android:layout_width="wrap_content"  //指定宽度
            android:layout_height="wrap_content" //指定高度
            android:text="Hello World!"                  //显示的文字
            android:gravity="center"             //文字对齐的方式,默认是左上角
            android:textSize="22sp"           //字体太小
            android:textColor="@color/colorAccent"    //字体颜色
            />
    

    2、Button

    2.1 padding与margin属性的讲解
        android:layout_margin="10dp"         //本元素离上下左右的距离
            android:layout_marginTop="10dp"      //顶部边缘离其它元素的距离
            android:layout_marginBottom="10dp"   //底部边缘离其它元素的距离
            android:layout_marginRight="10dp"    //右部边缘离其它元素的距离
            android:layout_marginLeft="10dp"     //左部边缘离其它元素的距离
            android:layout_marginStart="10"      //与layout_marginLeft效果一致
            android:layout_marginEnd="10dp"      //与layout_marginRight效果一致
    
            android:padding="10dp"        //元素内边距
            android:paddingTop="10dp"     //元素上边距
            android:paddingBottom="10dp"  //元素底边距
            android:paddingLeft="10dp"    //元素左边距
            android:paddingRight="10dp"   //元素右边距
    
    image.png
    2.2 禁止Button中的所有英文字母自动进行大小写转换

    android:textAllCaps="false"

    2.3 点击事件的3种写法
    2.3.1 匿名内部类
            Button button = (Button) findViewById(R.id.btn_1);
    
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    
                }
            });
    
    2.3.2 onClick属性
        <Button
            android:id="@+id/btn_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:onClick="buttonOnclic"
            />
    
    
        public void buttonOnclic(View view){
            Toast.makeText(this, "button", Toast.LENGTH_SHORT).show();
        }
    
    2.3.3 接口方式注册
    public class MainActivity extends AppCompatActivity  implements View.OnClickListener{
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Button button = (Button) findViewById(R.id.btn_1);
    
            button.setOnClickListener(this);
        }
        
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.btn_1:
                    //处理的逻辑
                    break;
                default:
                    break;
            }
        }
    }
    

    3、EditText

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/app_name"  //提示语
            android:maxLines="2"  //指定最大行是2,当文本长度超过之后,文本会向上滚动
            android:inputType="textPassword"  //数字类型(number) 文本类型(text) 电话类型(phone)等
            />
    

    4、ImageView

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitCenter"               //缩放方式
            android:src="@mipmap/ic_launcher"    //图片来源
            />
    

    scaleType选择的方式:

    fitCenter:默认的方式,表示图片会填充控件,不会让图片变形,图片居中显示
    fitXY:表示图片填充控件,但是允许图片拉伸
    centerCrop:以填充ImageView控件为目的,将原图的中心对准ImageView的中心,等比例放大原图,直到填充ImageView为止(指的是把ImageView的宽和高都填满),原图超出ImageView的部分就会做裁剪
    center:保持原图大小,显示在ImageView的中心,当原图的大小大于ImageView的大小,将会做裁剪处理
    matrix:不改变原图的大小,从ImageView的左上角开始绘制原图,超出部分将会做裁剪处理
    fitStart:把原图按比例扩大(缩小)到ImageView的高度,显示在ImageView的上部分
    fitEnd:把原图按比例扩大(缩小)到ImageView的高度,显示在ImageView的下部分
    centerInside:以原图完全显示为目的,将图片的内容完整居中显示,通过按比例缩小原图的宽高小于或者等于ImageView的宽高,如果原图的大小小于ImageView的大小,就显示不做处理
    

    5、ProgressBar

    默认样式

        <ProgressBar
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
    image.png

    进度条样式

        <ProgressBar
            android:id="@+id/pb"
            android:layout_centerInParent="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="?android:attr/progressBarStyleHorizontal"
            android:max="100"
            />
    
    public class MainActivity extends AppCompatActivity  implements View.OnClickListener{
    
        private ProgressBar progressBar;
        private Button button;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            button = (Button) findViewById(R.id.btn_1);
            progressBar = (ProgressBar) findViewById(R.id.pb);
    
            button.setOnClickListener(this);
        }
    
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.btn_1:
                    //处理的逻辑
                    int progress = progressBar.getProgress();
                    progress = progress + 10;
                    progressBar.setProgress(progress);
                    break;
                default:
                    break;
            }
        }
    }
    
    image.png
    android:visibility="visible"    表示控件可见
    android:visibility="gone"       表示控件不可见,并且不占据布局中的位置和大小
    android:visibility="invisible"  表示控件不可见,但是还占据布局中的位置和大小
    

    6、AlertDialog

    6.1 基本使用

    AlertDialog可以在当前的页面弹出对话框,该对话框是置顶于所有的界面元素之上,能够屏蔽其它控件的交互能力

    public class MainActivity extends AppCompatActivity  implements View.OnClickListener{
    
        private Button button;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            button = (Button) findViewById(R.id.btn_1);
    
    
            button.setOnClickListener(this);
        }
    
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.btn_1:
                  initAlertDialog("警告","倒计时开始","确定","取消");
                    break;
                default:
                    break;
            }
        }
    
        /**
         * 初始化AlertDialog
         */
        private void initAlertDialog(String title,String msg,String positiveComfirmTip,String negativeComfirmTip) {
            AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
            dialog.setTitle(title);
            dialog.setMessage(msg);
            dialog.setCancelable(false);
            dialog.setPositiveButton(positiveComfirmTip, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
    
                }
            });
            dialog.setNegativeButton(negativeComfirmTip, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
    
                }
            });
            dialog.show();
        }
    }
    
    
    image.png
    6.2 例子的使用

    dialog_custom.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:orientation="vertical">
    
    
        <EditText
            android:id="@+id/editText_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:ems="10"
            android:gravity="center"
            android:hint="输入用户名"
            android:inputType="textPersonName"/>
    
        <EditText
            android:id="@+id/editText_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:ems="10"
            android:gravity="center"
            android:hint="输入密码"
            android:inputType="textPassword"/>
    </LinearLayout>
    

    activity_dialog_demo.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="一般对话框"
            android:onClick="normalDialog"
        />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="列表对话框"
            android:onClick="listDialog"
          />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="单选对话框"
            android:onClick="singleDialog"
         />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="多选对话框"
            android:onClick="mulDialog"
        />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="自定义对话框"
            android:onClick="customDialog"
         />
    
    </LinearLayout>
    
    

    DialogDemoActivity.java文件

    public class DialogDemoActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_dialog_demo);
        }
    
        // 一般对话框
        public void normalDialog(View v) {
            //先得到构造器
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            //设置标题
            builder.setTitle("提示");
            builder.setMessage("是否确认退出");   //设置内容
            builder.setIcon(R.mipmap.ic_launcher); //自定义图标
            builder.setCancelable(false);           //设置是否能点击,对话框的其他区域取消
            //设置其确认按钮和监听事件
            builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            //设置其取消按钮和监听事件
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            //设置其忽略按钮和监听事件
            builder.setNeutralButton("忽略", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            // 下面两行代码 可以合成一行 builder.show()
            Dialog dialog=builder.create();       //创建对话框
            dialog.show();         //显示对话框
        }
    
        //列表对话框
        public void listDialog(View v) {
            final String items[] = {"AAA", "BBB", "CCC"};
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("提示"); //设置标题
            builder.setIcon(R.mipmap.ic_launcher);//设置图标,图片id即可
            //设置列表显示,注意设置了列表显示就不要设置builder.setMessage()了,否则列表不起作用。
            builder.setItems(items, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    Toast.makeText(getApplicationContext(), items[which], Toast.LENGTH_SHORT).show();
    
                }
            });
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    Toast.makeText(getApplicationContext(), "确定", Toast.LENGTH_SHORT).show();
                }
            });
            builder.create().show();
        }
    
        // 单选按钮对话框
        public void singleDialog(View v) {
            final String items[] = {"男", "未知", "女"};
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            //设置标题
            builder.setTitle("提示");
            //设置图标,图片id即可
            builder.setIcon(R.mipmap.ic_launcher);
    
            //设置单选按钮
            //  items   为列表项
            //  0       为默认选中第一个
            //  第三个参数是监听器
            builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Toast.makeText(getApplicationContext(), items[which], Toast.LENGTH_SHORT).show();
                }
            });
            //  设置监听器
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    Toast.makeText(getApplicationContext(), "确定", Toast.LENGTH_SHORT).show();
                }
            });
            builder.create().show();
        }
    
        // 多选对话框
        public void mulDialog(View v) {
            final String items[] = {"篮球", "足球", "排球"};
            final boolean selected[] = {true, false, true};
            AlertDialog.Builder builder = new AlertDialog.Builder(this);  //先得到构造器
            builder.setTitle("爱好"); //设置标题
            builder.setIcon(R.mipmap.ic_launcher);//设置图标,图片id即可
    
            //  参数一:列表项
            //  参数二:默认打勾的
            //  参数三:监听器
            builder.setMultiChoiceItems(items, selected,
                    new DialogInterface.OnMultiChoiceClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                            // dialog.dismiss();
                            Toast.makeText(getApplicationContext(),
                                    items[which] + isChecked, Toast.LENGTH_SHORT).show();
                        }
                    });
            //  确认按钮
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    Toast.makeText(getApplicationContext(), "确定", Toast.LENGTH_SHORT).show();
                    //android会自动根据你选择的改变selected数组的值。
                    for (int i = 0; i < selected.length; i++) {
                        Log.i("mulDialog", "" + selected[i]);
                    }
                }
            });
            builder.create().show();
        }
    
        // 自定义对话框
        public void customDialog(View v) {
    
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            //设置标题
            builder.setTitle("自定义dialog");
            //设置图标,图片id即可
            builder.setIcon(R.mipmap.ic_launcher);
            //  载入布局
            LayoutInflater inflater = getLayoutInflater();
            View layout = inflater.inflate(R.layout.dialog_custom, null);
            builder.setView(layout);
            //  初始化自定义布局中的控件, 因为控件在自定义layout中, 必须用layout.findViewByID
            EditText editText_name = (EditText) layout.findViewById(R.id.editText_name);
            EditText editText_password = (EditText) layout.findViewById(R.id.editText_password);
            //  确认按钮
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            //  显示
            builder.create().show();
        }
    }
    
    image.png

    7、ProgressDialog

    与AlertDialog有点类似,不同的就是ProgressDialog会显示一个进度条,一般表示当前操作是耗时的

        /**
         * 初始化initProgressDialog
         */
        private void initProgressDialog(String title,String message) {
            ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
            progressDialog.setTitle(title);
            progressDialog.setMessage(message);
            progressDialog.setCancelable(true);
            progressDialog.show();
    
        }
    
    image.png

    8、常用的基本布局

    image.png
    image.png
    8.1 线性布局

    android:orientation="vertical" 指定线性垂直布局

    android:orientation="horizontal" 指定线性水平布局

    android:layout_weight="" 线性布局很重要的一个特性,可以让控件按照屏幕的比例来缩放,是屏幕适配一个很好的应用

    8.2 相对布局

    与父布局相关的布局属性

            android:layout_centerInParent="true" //位于父布局的中央
            android:layout_alignParentLeft="true"//位于父布局的左边
            android:layout_alignParentRight="true"//位于父布局的右边
            android:layout_alignParentBottom="true"//位于父布局的底部
            android:layout_alignParentTop="true"//位于父布局的顶部
    
    

    与其它控件相关的布局属性

           android:layout_above="@id/btn_1" //位于某个控件的上面
          android:layout_below="@id/btn_1"  //位于某个控件的下面
          android:layout_toLeftOf="@id/btn_1"//位于某个控件的左边
          android:layout_toRightOf="@id/btn_1"//位于某个控件的右边
    
    image.png
    image.png
    image.png
    8.3 帧布局

    这种布局没有方便的地位方式,所有的控件都会默认摆放在布局的左上角,经常结合碎片来应用或者某些app上面的引导页也可以用帧布局来实现


    image.png
    8.4 百分比布局

    为了解决相对布局和帧布局在按照比例来指定控件大小的缺陷,从而引入了百分比布局

    image.png
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.percent.PercentFrameLayout
        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="com.example.uiwidgettest.SecondActivity">
    
        <Button
            android:id="@+id/button1"
            android:textAllCaps="false"
            android:text="Button1"
            android:layout_gravity="left|top"
            app:layout_widthPercent="50%"
            app:layout_heightPercent="50%"
            />
    
        <Button
            android:id="@+id/button2"
            android:textAllCaps="false"
            android:text="Button2"
            android:layout_gravity="right|top"
            app:layout_widthPercent="50%"
            app:layout_heightPercent="50%"
            />
    
        <Button
            android:id="@+id/button3"
            android:textAllCaps="false"
            android:text="Button3"
            android:layout_gravity="left|bottom"
            app:layout_widthPercent="50%"
            app:layout_heightPercent="50%"
            />
    
        <Button
            android:id="@+id/button4"
            android:textAllCaps="false"
            android:text="Button4"
            android:layout_gravity="right|bottom"
            app:layout_widthPercent="50%"
            app:layout_heightPercent="50%"
            />
    
    </android.support.percent.PercentFrameLayout>
    
    image.png
    8.5 GridLayout(网格布局)

    1)和LinearLayout一样有vertical(垂直)和horizontal(水平)这两种方式
    2)设置android:columnCount="4"列属性后,子控件会自动进行换行排列
    3)指定某控件在固定的行和列:
    android:layout_column="0" 在第一列开始
    android:layout_row="0" 在第一行开始

    8.5.1 计算器界面例子
    <?xml version="1.0" encoding="utf-8"?>
    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:columnCount="4"
        android:orientation="horizontal"
        android:rowCount="5">
          
        <Button
            android:id="@+id/one"
            android:text="1" />
          
        <Button
            android:id="@+id/two"
            android:text="2" />
           
        <Button
            android:id="@+id/three"
            android:text="3" />
        <Button
            android:id="@+id/devide"
            android:text="/" />
        <Button
            android:id="@+id/four"
            android:text="4" />
        <Button
            android:id="@+id/five"
            android:text="5" />
          
    
        <Button
            android:id="@+id/six"
            android:text="6" />
        <Button
            android:id="@+id/multiply"
            android:text="×" />
        <Button
            android:id="@+id/seven"
            android:text="7" />
    
        <Button
            android:id="@+id/eight"
            android:text="8" />
    
        <Button
            android:id="@+id/nine"
            android:text="9" />
    
        <Button
            android:id="@+id/minus"
            android:text="-" />
    
        <Button
            android:id="@+id/zero"
            android:layout_columnSpan="2"
            android:layout_gravity="fill"
            android:text="0" />
          
        <Button
            android:id="@+id/point"
            android:text="." />
    
        <Button
            android:id="@+id/plus"
            android:layout_gravity="fill"
            android:layout_rowSpan="2"
            android:text="+" />
    
        <Button
            android:id="@+id/equal"
            android:layout_columnSpan="3"
            android:layout_gravity="fill"
            android:text="=" />
    </GridLayout>
    
    image.png
    8.5.2 简单的登录界面例子
    <?xml version="1.0" encoding="utf-8"?>
    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:columnCount="4"
                android:orientation="horizontal"
                android:rowCount="4"
    >
        <TextView
            android:layout_gravity="center"
            android:layout_marginLeft="5dp"
            android:text="姓名:"/>
    
    
        <EditText
            android:layout_columnSpan="3"
            android:layout_gravity="fill"
            android:text=""
        />
    
        <TextView
            android:layout_gravity="center"
            android:layout_marginLeft="5dp"
            android:text="密码:"/>
    
        <EditText
            android:layout_columnSpan="3"
            android:layout_gravity="fill"
            android:inputType="textPassword"
            android:text=""
        />
    
        <Button
            android:layout_column="1"
            android:text="登录"
        />
    
    </GridLayout>
    
    8.6 CoordinatorLayout
    image.png
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout 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="com.example.printttest.MainActivity">
    
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/flb"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="15dp"
            android:src="@mipmap/ic_launcher"
            />
    
    
    
    </android.support.design.widget.CoordinatorLayout>
    

    9、 创建组合自定义控件的流程

    根据需求写出组合控件的布局:title.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:background="@drawable/title_bg">
    
        <Button
            android:id="@+id/title_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="5dp"
            android:background="@drawable/back_bg"
            android:text="Back"
            android:textColor="#fff" />
    
        <TextView
            android:id="@+id/title_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="center"
            android:text="Title Text"
            android:textColor="#fff"
            android:textSize="24sp" />
    
        <Button
            android:id="@+id/title_edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="5dp"
            android:background="@drawable/edit_bg"
            android:text="Edit"
            android:textColor="#fff" />
    
    </LinearLayout>
    

    自定义控件编码:TitleLayout.java

    public class TitleLayout extends LinearLayout {
    
        public TitleLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            View rootView = LayoutInflater.from(context).inflate(R.layout.title, this);
            Button titleBack = (Button) rootView.findViewById(R.id.title_back);
            Button titleEdit = (Button) rootView.findViewById(R.id.title_edit);
            titleBack.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    ((Activity) getContext()).finish();
                }
            });
            titleEdit.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(getContext(), "You clicked Edit button",
                            Toast.LENGTH_SHORT).show();
                }
            });
        }
    
    }
    

    布局上引用

    <android.support.constraint.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="com.example.uiwidgettest.Main2Activity">
    
    
        <com.example.uiwidgettest.TitleLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    
    </android.support.constraint.ConstraintLayout>
    

    主代码中显示

    public class Main2Activity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
    
            ActionBar actionBar = getSupportActionBar();
    
            if (actionBar != null){
                actionBar.hide();
            }
        }
    }
    
    
    image.png

    10、 ListView控件的基本使用

    10.1 标准使用例子

    数据实体类

    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;
        }
    }
    
    

    列表Item的布局

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

    数据适配器

    public class FruitAdapter extends ArrayAdapter<Fruit> {
    
        private int resourceId;
    
        public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
            super(context, resource, objects);
            this.resourceId = resource;
        }
    
        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            Fruit fruit = getItem(position);
            View view = null;
            ViewHolder viewHolder = null;
            if (convertView == null){
                view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
                viewHolder = new ViewHolder();
                viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
                viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);
                view.setTag(viewHolder);
            }else {
                view = convertView;
                viewHolder = (ViewHolder) view.getTag();
            }
    
    
            viewHolder.fruitImage.setImageResource(fruit.getImageId());
            viewHolder.fruitName.setText(fruit.getName());
            return view;
        }
    
    
        class ViewHolder{
            ImageView fruitImage;
    
            TextView fruitName;
        }
    }
    
    

    界面主布局

    <?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="com.example.uiwidgettest.ListViewActivity">
    
        <ListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        </ListView>
    
    </LinearLayout>
    

    主界面实现代码

    public class ListViewActivity extends AppCompatActivity {
    
        private List<Fruit> fruitList = new ArrayList<>();
        private ListView listView;
        private Context context;
        private FruitAdapter adapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_list_view);
    
            initView();
            
            initFruits();
    
            initListView();
        }
    
        private void initView() {
            context = this;
            listView = (ListView) findViewById(R.id.list_view);
    
        }
    
        private void initListView() {
            adapter = new FruitAdapter(context, R.layout.fruit_item,fruitList);
            listView.setAdapter(adapter);
    
            //ListView的点击事件
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    Fruit fruit = fruitList.get(i);
                    Toast.makeText(context, "你选择的是"+fruit.getName(), Toast.LENGTH_SHORT).show();
                }
            });
    
            //ListView的长按点击事件
            listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long l) {
                    fruitList.remove(position);
                    adapter.notifyDataSetChanged();
                    return true;
                }
            });
        }
    
        private void initFruits() {
            for (int i = 0; i < 2; i++) {
                Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
                fruitList.add(apple);
                Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
                fruitList.add(banana);
                Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
                fruitList.add(orange);
                Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
                fruitList.add(watermelon);
                Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
                fruitList.add(pear);
                Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
                fruitList.add(grape);
                Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
                fruitList.add(pineapple);
                Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
                fruitList.add(strawberry);
                Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
                fruitList.add(cherry);
                Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
                fruitList.add(mango);
            }
        }
    }
    
    image.png
    10.2 长按点击事件和点击事件的事件传递
    image.png
    10.3 ListView的常用属性
            android:divider=""  //设置分割线的颜色或者指定分割线的图片
            android:dividerHeight=""  //设置分割线的高度
            android:scrollbars="none"  //隐藏滚动条
    

    11、GridView控件的基本使用

    image.png

    Fruit,java文件

    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;
        }
    }
    
    

    gv_fruit_item.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <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="center"
            android:layout_marginTop="10dp"
              />
    
    </LinearLayout>
    

    FruitAdapter.java文件

    public class FruitAdapter extends ArrayAdapter<Fruit> {
    
        private int resourceId;
    
        public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
            super(context, resource, objects);
            this.resourceId = resource;
        }
    
        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            Fruit fruit = getItem(position);
            View view = null;
            ViewHolder viewHolder = null;
            if (convertView == null){
                view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
                viewHolder = new ViewHolder();
                viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
                viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);
                view.setTag(viewHolder);
            }else {
                view = convertView;
                viewHolder = (ViewHolder) view.getTag();
            }
    
    
            viewHolder.fruitImage.setImageResource(fruit.getImageId());
            viewHolder.fruitName.setText(fruit.getName());
            return view;
        }
    
    
        class ViewHolder{
            ImageView fruitImage;
    
            TextView fruitName;
        }
    }
    
    

    activity_grid_view.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="com.example.uiwidgettest.GridViewActivity">
    
        <GridView
            android:id="@+id/gv"
            android:numColumns="3"
            android:horizontalSpacing="10dp"
            android:verticalSpacing="10dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        </GridView>
    
    </LinearLayout>
    

    GridViewActivity.java文件

    public class GridViewActivity extends AppCompatActivity {
    
        private List<Fruit> fruitList = new ArrayList<>();
        private GridView gvView;
        private Context context;
        private FruitAdapter adapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_grid_view);
    
            initView();
    
            initFruits();
    
            initListView();
        }
    
        private void initView() {
            context = this;
            gvView = (GridView) findViewById(R.id.gv);
    
        }
    
        private void initListView() {
            adapter = new FruitAdapter(context, R.layout.gv_fruit_item,fruitList);
            gvView.setAdapter(adapter);
            gvView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    Fruit fruit = fruitList.get(i);
                    Toast.makeText(context, "你选择的是"+fruit.getName(), Toast.LENGTH_SHORT).show();
                }
            });
    
            gvView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long l) {
                    fruitList.remove(position);
                    adapter.notifyDataSetChanged();
                    return true;
                }
            });
        }
    
        private void initFruits() {
            for (int i = 0; i < 2; i++) {
                Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
                fruitList.add(apple);
                Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
                fruitList.add(banana);
                Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
                fruitList.add(orange);
                Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
                fruitList.add(watermelon);
                Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
                fruitList.add(pear);
                Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
                fruitList.add(grape);
                Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
                fruitList.add(pineapple);
                Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
                fruitList.add(strawberry);
                Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
                fruitList.add(cherry);
                Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
                fruitList.add(mango);
            }
        }
    }
    
    image.png

    11、 RecyclerView控件的基本使用

    image.png
    image.png
    11.1 垂直布局

    数据实体类

    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;
        }
    }
    
    

    列表Item布局(注意这个和ListView的区别)

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

    数据适配器

    public class FruitsAdapter extends RecyclerView.Adapter<FruitsAdapter.ViewHolder> {
    
        private List<Fruit> mFruitList;
    
        public FruitsAdapter(List<Fruit> mFruitList) {
            this.mFruitList = mFruitList;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
            ViewHolder viewHolder = new ViewHolder(view);
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(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 itemView) {
                super(itemView);
                fruitImage = (ImageView)itemView.findViewById(R.id.fruit_image);
                fruitName = (TextView)itemView.findViewById(R.id.fruit_name);
            }
        }
    }
    

    主界面布局

    <?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="com.example.uiwidgettest.RecyclerViewActivity">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        </android.support.v7.widget.RecyclerView>
    
    </LinearLayout>
    

    主界面逻辑代码

    public class RecyclerViewActivity extends AppCompatActivity {
    
        private RecyclerView recyclerView;
        private List<Fruit> fruitList = new ArrayList<>();
        private Context context;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_recycler_view);
    
            initView();
    
            initFruits();
    
            initRecycleView();
        }
    
    
    
        private void initView() {
            context = this;
            recyclerView = (RecyclerView) findViewById(R.id.rv);
        }
    
        private void initFruits() {
            for (int i = 0; i < 2; i++) {
                Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
                fruitList.add(apple);
                Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
                fruitList.add(banana);
                Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
                fruitList.add(orange);
                Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
                fruitList.add(watermelon);
                Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
                fruitList.add(pear);
                Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
                fruitList.add(grape);
                Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
                fruitList.add(pineapple);
                Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
                fruitList.add(strawberry);
                Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
                fruitList.add(cherry);
                Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
                fruitList.add(mango);
            }
        }
    
        private void initRecycleView() {
            FruitsAdapter adapter = new FruitsAdapter(fruitList);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
            recyclerView.setLayoutManager(linearLayoutManager);
            recyclerView.setAdapter(adapter);
        }
    
    }
    
    image.png
    11.2 横向布局

    修改上面的代码实现横向布局

    <?xml version="1.0" encoding="utf-8"?>
    <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_horizontal"
            android:layout_marginTop="10dp"
              />
    
    </LinearLayout>
    
    public class RecyclerViewActivity extends AppCompatActivity {
    
        private RecyclerView recyclerView;
        private List<Fruit> fruitList = new ArrayList<>();
        private Context context;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_recycler_view);
    
            initView();
    
            initFruits();
    
            initRecycleView();
        }
    
    
    
        private void initView() {
            context = this;
            recyclerView = (RecyclerView) findViewById(R.id.rv);
        }
    
        private void initFruits() {
            for (int i = 0; i < 2; i++) {
                Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
                fruitList.add(apple);
                Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
                fruitList.add(banana);
                Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
                fruitList.add(orange);
                Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
                fruitList.add(watermelon);
                Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
                fruitList.add(pear);
                Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
                fruitList.add(grape);
                Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
                fruitList.add(pineapple);
                Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);
                fruitList.add(strawberry);
                Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
                fruitList.add(cherry);
                Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
                fruitList.add(mango);
            }
        }
    
        private void initRecycleView() {
            FruitsAdapter adapter = new FruitsAdapter(fruitList);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
            linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
            recyclerView.setLayoutManager(linearLayoutManager);
    
            //GridView布局
            //recyclerView.setLayoutManager(new GridLayoutManager(this,3));
            recyclerView.setAdapter(adapter);
        }
    
    }
    
    image.png image.png
    11.3 瀑布流布局
    <?xml version="1.0" encoding="utf-8"?>
    <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_marginTop="10dp"
              />
    
    </LinearLayout>
    
    public class FruitsAdapter extends RecyclerView.Adapter<FruitsAdapter.ViewHolder> {
    
        private List<Fruit> mFruitList;
    
        public FruitsAdapter(List<Fruit> mFruitList) {
            this.mFruitList = mFruitList;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,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(), "你点击了整个View:"+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(), "你点击了图片:"+fruit.getName(), Toast.LENGTH_SHORT).show();
                }
            });
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(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{
    
            View fruitView;
            ImageView fruitImage;
            TextView fruitName;
    
            public ViewHolder(View itemView) {
                super(itemView);
                fruitView = itemView;
                fruitImage = (ImageView)itemView.findViewById(R.id.fruit_image);
                fruitName = (TextView)itemView.findViewById(R.id.fruit_name);
            }
        }
    }
    
    
    public class RecyclerViewActivity extends AppCompatActivity {
    
        private static final String TAG = RecyclerViewActivity.class.getSimpleName();
        private RecyclerView recyclerView;
        private List<Fruit> fruitList = new ArrayList<>();
        private Context context;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_recycler_view);
    
            initView();
    
            initFruits();
    
            initRecycleView();
        }
    
    
    
        private void initView() {
            context = this;
            recyclerView = (RecyclerView) findViewById(R.id.rv);
        }
    
        private void initFruits() {
            for (int i = 0; i < 2; i++) {
                Fruit apple = new Fruit(getRandomLengthName("Apple"), R.drawable.apple_pic);
                fruitList.add(apple);
                Fruit banana = new Fruit(getRandomLengthName("Banana"), R.drawable.banana_pic);
                fruitList.add(banana);
                Fruit orange = new Fruit(getRandomLengthName("Orange"), R.drawable.orange_pic);
                fruitList.add(orange);
                Fruit watermelon = new Fruit(getRandomLengthName("Watermelon"), R.drawable.watermelon_pic);
                fruitList.add(watermelon);
                Fruit pear = new Fruit(getRandomLengthName("Pear"), R.drawable.pear_pic);
                fruitList.add(pear);
                Fruit grape = new Fruit(getRandomLengthName("Grape"), R.drawable.grape_pic);
                fruitList.add(grape);
                Fruit pineapple = new Fruit(getRandomLengthName("Pineapple"), R.drawable.pineapple_pic);
                fruitList.add(pineapple);
                Fruit strawberry = new Fruit(getRandomLengthName("Strawberry"), R.drawable.strawberry_pic);
                fruitList.add(strawberry);
                Fruit cherry = new Fruit(getRandomLengthName("Cherry"), R.drawable.cherry_pic);
                fruitList.add(cherry);
                Fruit mango = new Fruit(getRandomLengthName("Mango"), R.drawable.mango_pic);
                fruitList.add(mango);
            }
        }
    
        private void initRecycleView() {
            FruitsAdapter adapter = new FruitsAdapter(fruitList);
            StaggeredGridLayoutManager linearLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
            recyclerView.setLayoutManager(linearLayoutManager);
            recyclerView.setAdapter(adapter);
        }
    
        private String getRandomLengthName(String name){
            Random random = new Random();
            int length = random.nextInt(20) + 1;
            Log.d(TAG,"length========="+length);
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < length; i++) {
                builder.append(name);
            }
            return builder.toString();
        }
    
    }
    
    image.png
    11.4 Recycleview点击事件的另外一种写法以及数据添加、删除

    FruitsAdapter2.java 文件

    public class FruitsAdapter2 extends RecyclerView.Adapter<FruitsAdapter2.ViewHolder> implements View.OnClickListener{
    
        private static final String TAG = FruitsAdapter2.class.getSimpleName();
        private List<Fruit> mFruitList;
    
        public FruitsAdapter2(List<Fruit> mFruitList) {
            this.mFruitList = mFruitList;
        }
    
    
        public OnRecyclerViewOnItemClickListener mOnItemClickListener;
    
    
        public void setOnRecyclerViewOnItemClickListener(OnRecyclerViewOnItemClickListener onRecyclerViewOnItemClickListener) {
            this.mOnItemClickListener = onRecyclerViewOnItemClickListener;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
            final ViewHolder viewHolder = new ViewHolder(view);
            viewHolder.fruitView.setOnClickListener(this);
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            Fruit fruit = mFruitList.get(position);
            holder.fruitImage.setImageResource(fruit.getImageId());
            holder.fruitName.setText(fruit.getName());
            holder.fruitView.setTag(position);
        }
    
        @Override
        public int getItemCount() {
            return mFruitList.size();
        }
    
    
        static class ViewHolder extends RecyclerView.ViewHolder{
    
            View fruitView;
            ImageView fruitImage;
            TextView fruitName;
    
            public ViewHolder(View itemView) {
                super(itemView);
                fruitView = itemView;
                fruitImage = (ImageView)itemView.findViewById(R.id.fruit_image);
                fruitName = (TextView)itemView.findViewById(R.id.fruit_name);
            }
        }
    
        @Override
        public void onClick(View view) {
    
            if (mOnItemClickListener != null){
                int position = (int) view.getTag();
                Fruit fruit = mFruitList.get(position);
                mOnItemClickListener.onItemClick(view,fruit,position);
            }
    
        }
    
        public void addItem(int position,Fruit fruit){
            if (mFruitList != null){
                mFruitList.add(position,fruit);
                notifyItemInserted(position);
                notifyItemChanged(position);     //通知重新绑定某一个Item的数据与界面
            }
        }
    
        public void deleteItem(int position,Fruit fruit){
            if (mFruitList != null && mFruitList.size() > 0){
                Log.d(TAG," mFruitList.size()==========="+ mFruitList.size());
                Log.d(TAG,"position==========="+position);
                mFruitList.remove(position);
                notifyDataSetChanged();     //通知重新绑定所有数据与界面
            }
        }
    
    
        public static interface OnRecyclerViewOnItemClickListener{
    
            void onItemClick(View itemView,Fruit item,int position);
        }
    }
    

    RecyclerViewActivity.java文件

    public class RecyclerViewActivity extends AppCompatActivity {
    
        private static final String TAG = RecyclerViewActivity.class.getSimpleName();
        private RecyclerView recyclerView;
        private List<Fruit> fruitList = new ArrayList<>();
        private Context context;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_recycler_view);
    
            initView();
    
            initFruits();
    
            initRecycleView();
        }
    
    
    
        private void initView() {
            context = this;
            recyclerView = (RecyclerView) findViewById(R.id.rv);
        }
    
        private void initFruits() {
            for (int i = 0; i < 2; i++) {
                Fruit apple = new Fruit(getRandomLengthName("Apple"), R.drawable.apple_pic);
                fruitList.add(apple);
                Fruit banana = new Fruit(getRandomLengthName("Banana"), R.drawable.banana_pic);
                fruitList.add(banana);
                Fruit orange = new Fruit(getRandomLengthName("Orange"), R.drawable.orange_pic);
                fruitList.add(orange);
                Fruit watermelon = new Fruit(getRandomLengthName("Watermelon"), R.drawable.watermelon_pic);
                fruitList.add(watermelon);
                Fruit pear = new Fruit(getRandomLengthName("Pear"), R.drawable.pear_pic);
                fruitList.add(pear);
                Fruit grape = new Fruit(getRandomLengthName("Grape"), R.drawable.grape_pic);
                fruitList.add(grape);
                Fruit pineapple = new Fruit(getRandomLengthName("Pineapple"), R.drawable.pineapple_pic);
                fruitList.add(pineapple);
                Fruit strawberry = new Fruit(getRandomLengthName("Strawberry"), R.drawable.strawberry_pic);
                fruitList.add(strawberry);
                Fruit cherry = new Fruit(getRandomLengthName("Cherry"), R.drawable.cherry_pic);
                fruitList.add(cherry);
                Fruit mango = new Fruit(getRandomLengthName("Mango"), R.drawable.mango_pic);
                fruitList.add(mango);
            }
        }
    
        private void initRecycleView() {
            final FruitsAdapter2 adapter = new FruitsAdapter2(fruitList);
    //        StaggeredGridLayoutManager linearLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
            recyclerView.setLayoutManager(new GridLayoutManager(this,3));
            recyclerView.setAdapter(adapter);
    
            adapter.setOnRecyclerViewOnItemClickListener(new FruitsAdapter2.OnRecyclerViewOnItemClickListener() {
                @Override
                public void onItemClick(View itemView, Fruit item, int position) {
    
                    //模拟删除数据
    //                adapter.deleteItem(position,item);
    
    
                    //模拟添加数据
                    Fruit fruit = new Fruit("水蜜桃",R.drawable.apple_pic);
                    //表示要插入数据的位置
                    int insertPosition = 0;
                    if (fruitList != null){
                        int size = fruitList.size();
                        insertPosition = size;
                    }
                    adapter.addItem(insertPosition,fruit);
                    recyclerView.scrollToPosition(fruitList.size()-1);
                }
            });
        }
    
        private String getRandomLengthName(String name){
            Random random = new Random();
            int length = random.nextInt(20) + 1;
            Log.d(TAG,"length========="+length);
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < length; i++) {
                builder.append(name);
            }
            return builder.toString();
        }
    
    }
    
    
    image.png

    12、Recycleview的综合练习

    数据实体类

    public class Msg {
    
        public static final int TYPE_RECEIVED = 0;
    
        public static final int TYPE_SENT = 1;
    
        private String content;
    
        private int type;
    
        public Msg(String content, int type) {
            this.content = content;
            this.type = type;
        }
    
        public String getContent() {
            return content;
        }
    
        public int getType() {
            return type;
        }
    
    }
    
    

    列表Item布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp" >
    
        <LinearLayout
            android:id="@+id/left_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"
            android:background="@drawable/message_left" >
    
            <TextView
                android:id="@+id/left_msg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_margin="10dp"
                android:textColor="#fff" />
    
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/right_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:background="@drawable/message_right" >
    
            <TextView
                android:id="@+id/right_msg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_margin="10dp" />
    
        </LinearLayout>
    
    </LinearLayout>
    

    数据适配器

    public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder> {
    
        private List<Msg> mMsgList;
    
    
        public MsgAdapter(List<Msg> msgList) {
            mMsgList = msgList;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item, parent, false);
            return new ViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            Msg msg = mMsgList.get(position);
            if (msg.getType() == Msg.TYPE_RECEIVED) {
                // 如果是收到的消息,则显示左边的消息布局,将右边的消息布局隐藏
                holder.leftLayout.setVisibility(View.VISIBLE);
                holder.rightLayout.setVisibility(View.GONE);
                holder.leftMsg.setText(msg.getContent());
            } else if(msg.getType() == Msg.TYPE_SENT) {
                // 如果是发出的消息,则显示右边的消息布局,将左边的消息布局隐藏
                holder.rightLayout.setVisibility(View.VISIBLE);
                holder.leftLayout.setVisibility(View.GONE);
                holder.rightMsg.setText(msg.getContent());
            }
        }
    
        @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 = (LinearLayout) view.findViewById(R.id.left_layout);
                rightLayout = (LinearLayout) view.findViewById(R.id.right_layout);
                leftMsg = (TextView) view.findViewById(R.id.left_msg);
                rightMsg = (TextView) view.findViewById(R.id.right_msg);
            }
        }
    
    
    }
    
    

    主界面布局

    <?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"
        android:orientation="vertical"
        android:background="#d8e0e8"
        tools:context="com.example.uiwidgettest.ChatActivity">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/msg_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" >
    
            <EditText
                android:id="@+id/input_text"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:hint="Type something here"
                android:maxLines="2" />
    
            <Button
                android:id="@+id/send"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Send" />
    
        </LinearLayout>
    
    </LinearLayout>
    
    

    主界面逻辑代码

    public class ChatActivity extends AppCompatActivity {
    
        private List<Msg> msgList = new ArrayList<Msg>();
    
        private EditText inputText;
    
        private Button send;
    
        private RecyclerView msgRecyclerView;
    
        private MsgAdapter adapter;
    
        private Context context;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_chat);
    
            initView();
    
            initChatData();
    
            initRecyclerView();
    
            initListener();
    
        }
    
        private void initListener() {
            send.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String content = inputText.getText().toString();
                    if (!"".equals(content)) {
                        Msg msg = new Msg(content, Msg.TYPE_SENT);
                        msgList.add(msg);
                        adapter.notifyItemInserted(msgList.size() - 1); // 当有新消息时,刷新ListView中的显示
                        msgRecyclerView.scrollToPosition(msgList.size() - 1); // 将ListView定位到最后一行
                        inputText.setText(""); // 清空输入框中的内容
                    }
                }
            });
        }
    
        private void initRecyclerView() {
            LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            msgRecyclerView.setLayoutManager(layoutManager);
            adapter = new MsgAdapter(msgList);
            msgRecyclerView.setAdapter(adapter);
        }
    
        private void initChatData() {
            Msg msg1 = new Msg("Hello guy.", Msg.TYPE_RECEIVED);
            msgList.add(msg1);
            Msg msg2 = new Msg("Hello. Who is that?", Msg.TYPE_SENT);
            msgList.add(msg2);
            Msg msg3 = new Msg("This is Tom. Nice talking to you. ", Msg.TYPE_RECEIVED);
            msgList.add(msg3);
        }
    
        private void initView() {
            context = this;
            inputText = (EditText) findViewById(R.id.input_text);
            send = (Button) findViewById(R.id.send);
            msgRecyclerView = (RecyclerView) findViewById(R.id.msg_recycler_view);
        }
    }
    
    
    image.png

    13、Toast的使用

    13.1 Toast的创建方式
            //创建Toast的两种方式
            //直接使用字符串
            Toast.makeText(mContext, "", Toast.LENGTH_SHORT).show();
    
            //引用资源字符串
            Toast.makeText(mContext, R.string.app_name, Toast.LENGTH_SHORT).show();
    
    13.2 修改Toast的显示位置

    第一种方法:toast.setMargin(float horizontalMargin, float verticalMargin)

    第二种方法:toast.setGravity(int gravity, int xOffset, int yOffset);

    13.3 自定义Toast布局
        private void showToast(Context context){
            Toast toast = new Toast(context);
    
            //代码创建自定义样式
            ImageView iv = new ImageView(context);
            iv.setImageResource(R.mipmap.ic_launcher);
            LinearLayout linearLayout = new LinearLayout(context);
            linearLayout.setOrientation(LinearLayout.HORIZONTAL);
            linearLayout.addView(iv);
    
            //引用布局的方式
    //        LayoutInflater inflater = getLayoutInflater();
    //        View inflate = inflater.inflate(R.layout.toast, null);
    //        toast.setView(inflate);
            
            toast.setDuration(Toast.LENGTH_SHORT);
            toast.setView(linearLayout);
        }
    
    13.4 注意避免Toast因此的内存泄漏

    什么是内存泄漏?

        就是该回收的内存由于种种原因没有被回收,还驻留在内存中。说白了就是站着茅坑不拉屎,很容易导致厕所满员了,着急上厕所的人上不了。
    

    如下的代码:
    Toast.makeText(mContext, "", Toast.LENGTH_SHORT).show();

    如果Toast在没有消失之前,点击返回键结束了页面,因为toast持有了Activity的实例,该Activity没有真正销毁,这个Activity就会造成内存泄漏。

    解决方法:
    Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT).show();

    14、Snackbar的使用

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout 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:id="@+id/rootview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.snackbardemo.MainActivity">
    
    
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/flb"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@mipmap/ic_launcher"
            android:layout_gravity="bottom|end"
            android:layout_margin="20dp"
            />
    
    
    </android.support.design.widget.CoordinatorLayout>
    
    public class MainActivity extends AppCompatActivity {
    
        private FloatingActionButton flbActionBar;
        private CoordinatorLayout rootView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            rootView = (CoordinatorLayout) findViewById(R.id.rootview);
            flbActionBar = (FloatingActionButton) findViewById(R.id.flb);
    
            flbActionBar.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Snackbar.make(rootView,"Test! Test!",Snackbar.LENGTH_SHORT)
                            .setAction("确定", new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    Toast.makeText(MainActivity.this, "点击了确定按钮!", Toast.LENGTH_SHORT).show();
                                }
                            })
                            .show();
                }
            });
    
        }
    }
    
    
    image.png

    注意点:
    1)、make方法的第一个参数是一个View,不是上下文Context对象,任何一个View都可以,官方推荐使用CoordinatorLayout,这样做有俩个好处:
    1:用户右滑可以消除Snackbar
    2:当Snackbar出现时,布局会移动一下UI元素,比如右下角的浮动按钮在Snackbar出现时,会向上移动

    2)、View不一定是要是CoordinatorLayout,该方法触发时会一步一步向上查找,有没有CoordinatorLayout,如果找到顶层还没有就停止查找,所以最好是用CoordinatorLayout布局,这样就不用系统一步一步去查找

    3)、如果布局是已经写好了的,没有CoordinatorLayout,可以在最外层加一个CoordinatorLayout,CoordinatorLayout相当于一个超级帧布局

    15、Lambda表达式

    15.1 什么是Lambda表达式?

    该表达式允许我们将行为传递函数中,之前我们将行为传递函数中采用的是匿名内部类,该方法导致函数最重要的部分夹在中间,不过突出,例如:

            flbActionBar.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    showView();
                }
            });
    

    采用Lambda表达式后,就是一行代码

    flbActionBar.setOnClickListener(v -> showView());
    
    15.2 lambda表达式的基本格式
        () -> {}
    
        有下面三种表达形式:
        1、(params) -> expressions
        2、(params) -> statement
        3、(params) -> {statement}
    
    15.3 配置
        //编译支持java8
        compileOptions{
            sourceCompatibility 1.8
            targetCompatibility 1.8
    
            //或者写成下面这个样子
    //        sourceCompatibility JavaVersion.VERSION_1_8
    //        targetCompatibility JavaVersion.VERSION_1_8
        }
    

    16、ViewPager的简单使用

    创建3个view布局
    layou_view_one.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimaryDark"
        >
    
    </android.support.constraint.ConstraintLayout>
    

    layou_view_two.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        >
    
    </android.support.constraint.ConstraintLayout>
    

    layou_view_three.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"
        >
    
    </android.support.constraint.ConstraintLayout>
    

    activity_view_pager.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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="com.example.uiwidgettest.ViewPagerActivity">
    
        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            >
    
        </android.support.v4.view.ViewPager>
    
    </RelativeLayout>
    

    ViewPagerAdapter.java文件

    public class ViewPagerAdapter extends PagerAdapter {
    
        private List<View> mViewList;
    
        public ViewPagerAdapter(List<View> viewList) {
            this.mViewList = viewList;
        }
    
        @Override
        public int getCount() {
            return mViewList.size();
        }
    
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View view = mViewList.get(position);
            container.addView(view);
            return view;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            View view = mViewList.get(position);
            container.removeView(view);
        }
    }
    
    

    ViewPagerActivity.java文件

    public class ViewPagerActivity extends AppCompatActivity {
    
        private Context mContext;
        private ViewPager viewPager;
        private List<View> mListView = new ArrayList<>();
        private LayoutInflater inflater;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_view_pager);
    
            initView();
    
            initData();
    
            initViewPager();
        }
    
        private void initViewPager() {
            ViewPagerAdapter adapter = new ViewPagerAdapter(mListView);
            viewPager.setAdapter(adapter);
            viewPager.setOffscreenPageLimit(mListView.size());
    
            viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
                }
    
                @Override
                public void onPageSelected(int position) {
    
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
        }
    
    
        private void initData() {
            inflater = LayoutInflater.from(mContext);
            View viewOne = inflater.inflate(R.layout.layou_view_one, null);
            View viewTwo = inflater.inflate(R.layout.layou_view_two, null);
            View viewThree = inflater.inflate(R.layout.layou_view_three, null);
    
            mListView.add(viewOne);
            mListView.add(viewOne);
            mListView.add(viewThree);
        }
    
        private void initView() {
            mContext = this;
            viewPager = (ViewPager) findViewById(R.id.vp);
    
        }
    }
    
    
    image.png

    相关文章

      网友评论

      • IT人故事会:经常看别人的分享.感谢别人的分享,感谢!关注了

      本文标题:第3章 UI开发的点点滴滴

      本文链接:https://www.haomeiwen.com/subject/hsglkftx.html