android基础知识学习笔记Android面试好文章Android控件

第3章 UI开发的点点滴滴

2018-04-15  本文已影响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
上一篇 下一篇

猜你喜欢

热点阅读