栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

CH3-Android常见界面控件

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CH3-Android常见界面控件

文章目录

目标一、简单控件的使用

1.1 TextView控件1.2 EditText控件1.3 Button控件1.4 ImageView控件1.5 RadioButton控件1.6 CheckBox控件1.7 Toast类1.8 实战演练—实现注册界面效果 二、列表控件的使用

目标2.1 ListView控件2.2 常用数据适配器(Adapter)

baseAdapterSimpleAdapterArrayAdapter 2.3 实战演练—购物商城2.4 RecyclerView控件2.5 实战演练—动物列表2.5 实战演练—仿今日头条 三、自定义控件

目标

目标
    掌握简单控件的使用,能够独立搭建一个注册界面掌握ListView控件与RecyclerView控件的使用,能独立搭建列表界面掌握自定义控件的定义方式,能够自定义一个简单的控件

​ 几乎每一个Android应用都是通过界面控件与用户交互的,Android提供了非常丰富的界面控件,借助这些控件,我们可以很方便地进行用户界面开发。接下来,本章将针对Android常见的界面控件进行讲解。

一、简单控件的使用 1.1 TextView控件

控件是界面组成的主要元素,为了显示界面上的输入框、图片、文字等信息,Android系统提供了一些控件来显示这些信息,每个控件都有对应的属性来设置不同的效果。我们以控件使用的复杂程度将Android中的控件分别简单控件和列表控件,简单控件包含以下几种,具体如下图所示。

[外链图片转存中…(img-Mb4M1lUB-1645971864924)]

TextView控件用于显示文本信息,我们可以在XML布局文件中以添加属性的方式来控制TextView控件的样式, TextView控件的属性如下表所示。

属性名称功能描述
android:layout_width设置TextView控件的宽度
android:layout_height设置TextView控件的高度
android:id设置TextView控件的唯一标识
android:background设置TextView控件的背景
android:layout_margin设置当前控件与屏幕边界或周围控件、布局的距离 (外边距)
android:padding设置TextView控件与该控件中内容的距离 (内边距)
android:text设置文本内容
android:textColor设置文字显示的颜色
android:textSize设置文字大小,推荐单位为sp
android:gravity设置文本内容的位置
android:maxLength设置文本最大长度,超出此长度的文本不显示
android:lines设置文本的行数,超出此行数的文本不显示
android:maxLines设置文本的最大行数,超出此行数的文本不显示。
android:ellipsize设置当文本超出TextView规定的范围的显示方式。
android:drawableTop在文本的顶部显示图像
android:lineSpacingExtra设置文本的行间距
android:textStyle设置文本样式,如bold(粗体),italic(斜体),normal(正常)

​ 接下来,我们通过一个案例讲解如何将TextView控件中的文本信息居中,并且将文本的字体设置为斜体进行显示,显示斜体文本的界面效果如下图所示。

放置界面控件

在res/layout文件夹的activity_main.xml文件中,放置1个TextView控件,用于显示文本信息。



    

1.2 EditText控件

EditText表示编辑框,它是TextView的子类,用户可在此控件中输入信息。除了支持TextView控件的属性外,EditText还支持一些其它的常用属性,这些常用属性如下表所示。

属性名称功能描述
android:hint控件中内容为空时显示的提示文本信息
android:textColorHint控件中内容为空时显示的提示文本信息的颜色
android:password输入文本框中的内容显示为“.”
android:phoneNumber设置输入文本框中的内容只能是数字
android:maxLines设置文本的最大行数
android:scrollHorizontally设置文本信息超出EditText的宽度情况下,是否出现横拉条
android:editable设置是否可编辑

​ 接下来,我们通过一个案例来讲解如何使用EditText控件编辑文本信息,本案例中显示编辑框的界面效果如下图所示。

创建程序

​ 创建一个名为EditText的应用程序,指定包名为cn.itcast.edittext。

放置界面控件

​ 在activity_main.xml文件中,放置1个TextView控件,用于显示标题,1个EditText控件,供用户输入文本信息。



    
    

1.3 Button控件

Button控件表示按钮,它继承TextView控件,既可以显示文本,又可以显示图片,同时也允许用户通过点击来执行操作,当Button控件被点击时,被按下与弹起的背景会有一个动态的切换效果,这个效果就是点击效果 。

Button控件设置点击事件的方式有三种,具体如下所示。

(1)在布局文件中指定onClick属性的方式设置点击事件

(2)使用匿名内部类的方式设置点击事件

btn_one.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) { //按钮2的点击事件
        btn_one.setText("按钮1已被点击");
    }
});

(3)Activity实现OnClickListener接口的方式设置点击事件

public void click(View view) {
        btn_two.setText("按钮2已被点击");
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_three:     //按钮3的点击事件
                btn_three.setText("按钮3已被点击");
                break;
        }
    }

注意:实现Button控件的点击事件的三种方式中,前两种方式适合界面上Button控件较少的情况,如果界面上Button控件较多时,建议使用第三种方式实现控件的点击事件。

[外链图片转存中…(img-FicCqMC7-1645971864927)]

1.4 ImageView控件

ImageView控件表示图片,它继承自View,可以加载各种图片资源。ImageView控件的常用属性如下表所示。

属性名称功能描述
android:layout_width设置ImageView控件的宽度
android:layout_height设置ImageView控件的高度
android:id设置ImageView控件的唯一标识
android:background设置ImageView控件的背景
android:layout_margin设置当前控件与屏幕边界或周围控件的距离
android:src设置ImageView控件需要显示的图片资源
android:scaleType将图片资源缩放或移动,以适应ImageView控件的宽高
android:tint将图片渲染成指定的颜色

[外链图片转存中…(img-sF2bT4cB-1645971864928)]

reslayoutactivity_main.xml下放置界面控件



    
    

1.5 RadioButton控件

RadioButton表示单选按钮,它是Button的子类。每一个单选按钮都有“选中”和“未选中”两种状态,这两种状态是通过android:checked属性指定的。当可选值为true时,表示选中状态,否则,表示未选中状态。

​ 在XML布局文件中,RadioGroup和RadioButton配合使用的语法格式如下


	
	......

​ 接下来,我们通过一个案例来讲解如何使用RadioGroup和RadioButton实现单选按钮的功能。本案例的界面效果如下图所示。

[外链图片转存中…(img-QNCcuLKa-1645971864928)]

reslayoutactivity_main.xml下放置界面控件



    
        
        
    
    

radiobuttonMainActivity.java下设置监听事件

package cn.itcast.radiobutton;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RadioGroup;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private RadioGroup radioGroup;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        radioGroup = findViewById(R.id.rdg);
        textView = findViewById(R.id.tv);
        //利用setonCheckedChangeListener()为RadioGroup设置监听事件
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                //判断被点击的是哪一个RadioButton控件
                if (checkedId == R.id.rbtn) {
                    textView.setText("您的性别是:男");
                } else {
                    textView.setText("您的性别是:女");
                }
            }
        });
    }
}
1.6 CheckBox控件

CheckBox表示复选框,它是Button的子类,用于实现多选功能。每一个复选框都有“选中”和“未选中”两种状态,这两种状态是通过android:checked属性指定的,当该属性的值为true时,表示选中状态,否则,表示未选中状态。

[外链图片转存中…(img-MhNdiGHd-1645971864929)]

reslayoutactivity_main.xml下放置界面控件



    
    
    
    
    
    

checkboxMainActivity.java下实现控件的点击事件

package cn.itcast.checkbox;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements
        CompoundButton.OnCheckedChangeListener {
    private TextView hobby;
    private String hobbys;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化CheckBox控件
        CheckBox shuttlecock = findViewById(R.id.like_shuttlecock);
        CheckBox basketball =  findViewById(R.id.like_basketball);
        CheckBox pingpong = findViewById(R.id.like_pingpong);
        shuttlecock.setOnCheckedChangeListener(this);
        basketball.setOnCheckedChangeListener(this);
        pingpong.setOnCheckedChangeListener(this);
        hobby = findViewById(R.id.hobby);
        hobbys = new String();//存放选中的CheckBox的文本信息
    }
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        String motion = buttonView.getText().toString();
        if(isChecked){
            if(!hobbys.contains(motion)){
                hobbys = hobbys + motion;
                hobby.setText(hobbys);
            }
        }else {
            if (hobbys.contains(motion)) {
                hobbys = hobbys.replace(motion, "");
                hobby.setText(hobbys);
            }
        }
    }
}
1.7 Toast类

​ Toast是Android系统提供的轻量级信息提醒机制,用于向用户提示即时消息,它显示在应用程序界面的最上层,显示一段时间后自动消失不会打断当前操作,也不获得焦点。

使用Toast显示提示信息的示例代码如下:

Toast.makeText(Context,Text,Time).show();

关于makeText()方法中参数的相关介绍具体如下:

Context:表示应用程序环境的信息,即当前组件的上下文环境。Text:表示提示的字符串信息。Time:表示显示信息的时长,其属性值包括Toast.LENGTH_SHORT和Toast.LENGTH_LONG,分别表示显示较短时间和较长时间。

MainActivity.java使用Toast提示用户“WIFI已断开”的信息,示例代码如下:

package cn.itcast.toast;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toast.makeText(MainActivity.this, "WIFI已断开", Toast.LENGTH_SHORT).show();
    }
}

Toast提示用户“WIFI已断开”信息的效果如右图所示。

1.8 实战演练—实现注册界面效果

​ 接下来我们通过实现一个注册界面的功能来演示如何使用Android程序中常用的简单控件,注册界面的效果如下图所示。

[外链图片转存中…(img-cw8MhOv6-1645971864930)]

reslayoutactivity_main.xml下放置界面控件



    
        
        
            
            
            
        
        
        
            
            
        
        
        
            
            
        
        
        
            
            
        
        
        
            
            
        
        
        
            
            
                
                
            
        
        
        
            
            
            
            
        
        
    
    
    

resvaluesstyles.xml下创建样式



    
    
    
    
    
    
    


srcmainAndroidManifest.xml下去掉默认标题栏




    
        
        
            
                

                
            
        
    


checkboxMainActivity.java下实现注册功能

package cn.itcast.register;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
    private EditText et_name, et_email, et_pwd;
    private Button btn_submit;
    private String name, email, pwd, sex, hobbys;
    private RadioGroup rg_sex;
    private CheckBox cb_sing,cb_dance,cb_read;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
    private void init() {
        //获取界面控件
        et_name = findViewById(R.id.et_name);
        et_email = findViewById(R.id.et_email);
        et_pwd = findViewById(R.id.et_pwd);
        rg_sex = findViewById(R.id.rg_sex);
        cb_sing = findViewById(R.id.cb_sing);
        cb_dance = findViewById(R.id.cb_dance);
        cb_read = findViewById(R.id.cb_read);
        btn_submit = findViewById(R.id.btn_submit);
        btn_submit.setOnClickListener(this);//设置提交按钮的点击事件的监听器
        //设置复选框控件的点击事件的监听器
        cb_sing.setOnCheckedChangeListener(this);
        cb_dance.setOnCheckedChangeListener(this);
        cb_read.setOnCheckedChangeListener(this);
        hobbys=new String();
        //设置单选按钮的点击事件
        rg_sex.setOnCheckedChangeListener(new RadioGroup.
                OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId){ //判断被点击的RadioButton
                    case R.id.rb_boy:
                        sex = "男";
                        break;
                    case R.id.rb_girl:
                        sex = "女";
                        break;
                }
            }
        });
    }
    
    private void getData() {
        name = et_name.getText().toString().trim();
        email = et_email.getText().toString().trim();
        pwd = et_pwd.getText().toString().trim();
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_submit: //提交按钮的点击事件
                getData();
                if (TextUtils.isEmpty(name)) {
                    Toast.makeText(MainActivity.this, "请输入名字",
                            Toast.LENGTH_SHORT).show();
                } else if (TextUtils.isEmpty(email)) {
                    Toast.makeText(MainActivity.this, "请输入邮箱",
                            Toast.LENGTH_SHORT).show();
                } else if (TextUtils.isEmpty(pwd)) {
                    Toast.makeText(MainActivity.this, "请输入密码",
                            Toast.LENGTH_SHORT).show();
                } else if (TextUtils.isEmpty(sex)) {
                    Toast.makeText(MainActivity.this, "请选择性别",
                            Toast.LENGTH_SHORT).show();
                } else if (TextUtils.isEmpty(hobbys)) {
                    Toast.makeText(MainActivity.this, "请选择兴趣爱好",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "注册成功",
                            Toast.LENGTH_SHORT).show();
                    Log.i("MainActivity","注册的用户信息:"+"名字:"+name+", 邮箱:"
                            +email+", 性别:"+sex+", 兴趣爱好:"+hobbys);
                }
                break;
        }
    }
    
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        String motion = buttonView.getText().toString();//获取复选框中的内容
        if (isChecked) {
            if (!hobbys.contains(motion)) { //判断之前选择的内容是否与此次选择的不一样
                hobbys = hobbys + motion;
            }
        } else {
            if (hobbys.contains(motion)) {
                hobbys = hobbys.replace(motion, "");
            }
        }
    }
}
二、列表控件的使用 目标

掌握ListView控件的使用,能够独立搭建购物商城界面掌握RecyclerView控件的使用,能够独立搭建仿今日头条推荐列表界面 2.1 ListView控件

​ 在Android开发中,ListView是一个比较常用的控件,它以列表的形式展示数据内容,并且能够根据列表的高度自适应屏幕显示。ListView的样式是由属性决定的,它的常用属性如下表所示。

属性名称功能描述
android:listSelector当条目被点击后,改变条目的背景颜色
android:divider设置分割线的颜色
android:dividerHeight设置分割线的高度
android:scrollbars是否显示滚动条
android:fadingEdge去掉上边和下边的黑色阴影

​ 在XML文件的RelativeLayout布局中添加ListView控件的示例代码如下:



       
       

2.2 常用数据适配器(Adapter)

数据适配器是数据与视图之间的桥梁,它类似于一个转换器,将复杂的数据转换成用户可以接受的方式进行呈现。

常用的数据适配器:

baseAdapter:基本的适配器

SimpleAdapter:继承自baseAdapter

ArrayAdapter:也是baseAdapter的子类

baseAdapter

​ baseAdapter顾名思义是基本的适配器。它实际上是一个抽象类,通常在自定义适配器时会继承baseAdapter,该类拥有四个抽象方法,根据这几个抽象方法对ListView控件进行数据适配。baseAdapter中的4个抽象方法如下表所示。

方法名称功能描述
public int getCount()获取列表条目的总数
public Object getItem(int position)根据position(位置)获取某个条目的对象
public long getItemId(int position)根据position(位置)获取某个条目的id
public View getView(int position, View convertView, ViewGroup parent)获取相应position对应的条目视图,position是当前条目的位置,convertView用于复用旧视图,parent用于加载XML布局。
SimpleAdapter

​ SimpleAdapter继承baseAdapter,实现了baseAdapter的四个抽象方法并进行封装。SimpleAdapter的构造方法的具体信息如下:

  public SimpleAdapter(
      Context context, List> data, 
      int resource, String[] from, int[] to
  )

在SimpleAdapter()构造方法中的5个参数的含义如下:

context:表示上下文对象。data:数据集合,data中的每一项对应ListView控件中的条目的数据。resource:条目布局的资源id。from:Map集合中的key值。to:条目布局中对应的控件。 ArrayAdapter

​ ArrayAdapter也是baseAdapter的子类,用法与SimpleAdapter类似,开发者只需要在构造方法里面传入相应参数即可。ArrayAdapter通常用于适配TextView控件,ArrayAdapter有多个构造方法,构造方法的具体信息如下所示。

   public ArrayAdapter(Context context,int resource);
   public ArrayAdapter(Context context,int resource, int textViewResourceId);
   public ArrayAdapter(Context context,int resource,T[] objects);
   public ArrayAdapter(Context context,int resource,int textViewResourceId,T[] objects);
   public ArrayAdapter(Context context,int resource,List objects);
   public ArrayAdapter(Context context,int resource,int textViewResourceId, List objects)

在ArrayAdapter()构造方法中的4个参数的含义如下:

context:表示上下文对象。resource:条目布局的资源id。textViewResourceId: 条目布局中对应的TextView控件的idList objects: 需要适配的List类型的数据 2.3 实战演练—购物商城

​ 接下来我们通过一个购物商城的案例来演示如何通过ListView控件与数据适配器显示一个商品信息的列表。本案例的界面效果如下图所示。

[外链图片转存中…(img-d0KGXxqO-1645971864931)]

reslayoutactivity_main.xml下放置界面控件



    
    

reslayoutlist_item.xml创建列表条目



    
    
        
        
        
    

ListViewMainActivity.java下实现界面显示功能

package cn.itcast.listview;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.baseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
    private ListView mListView;
    //商品名称与价格数据集合
    private String[] titles = {"桌子", "苹果", "蛋糕", "线衣", "猕猴桃", "围巾"};
    private String[] prices = {"1800元", "10元/kg", "300元", "350元", "10元/kg",
            "280元"};
    //图片数据集合
    private int[] icons = {R.drawable.table, R.drawable.apple, R.drawable.cake,
            R.drawable.wireclothes, R.drawable.kiwifruit, R.drawable.scarf};

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = findViewById(R.id.lv); //初始化ListView控件
        MybaseAdapter mAdapter = new MybaseAdapter(); //创建一个Adapter的实例
        mListView.setAdapter(mAdapter);                  //设置Adapter
    }

    class MybaseAdapter extends baseAdapter {
        @Override
        public int getCount() {   //获取条目的总数
            return titles.length; //返回条目的总数
        }

        @Override
        public Object getItem(int position) {
            return titles[position]; //返回条目的数据对象
        }

        @Override
        public long getItemId(int position) {
            return position; //返回条目的Id
        }
        //获取条目的视图
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                //将list_item.xml文件找出来并转换成View对象
                convertView = View.inflate(MainActivity.this, R.layout.list_item, null);
                //找到list_item.xml中创建的TextView
                holder = new ViewHolder();
                holder.title =  convertView.findViewById(R.id.title);
                holder.price = convertView.findViewById(R.id.price);
                holder.iv = convertView.findViewById(R.id.iv);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.title.setText(titles[position]);
            holder.price.setText(prices[position]);
            holder.iv.setBackgroundResource(icons[position]);
            return convertView;
        }
        class ViewHolder {
            TextView title, price;
            ImageView iv;
        }
    }
}

优化ListView加载数据逻辑

​ 运行前面的购物商城程序后,当ListView控件上加载的条目过多,并快速滑动该列表控件时,界面会出现卡顿的现象,出现这个现象的原因如下:

(1)当滑动屏幕时,不断地创建条目对象

(2)不断执行findViewById()方法初始化界面控件

​ 由于上述两点原因,我们需要对ListView控件进行优化,优化目的是使ListView控件在快速滑动时不再重复创建条目对象,减少内存的消耗和屏幕渲染的处理。优化方式有以下两种:

(1)使用ViewHolder类

(2)复用convertView

​ 为了防止数据量过大造成内存溢出,在使用ListView时通常会进行优化,优化方式中的其中一种是复用convertView。

2.4 RecyclerView控件

​ RecyclerView与ListView控件相似,同样是以列表的形式展示数据,并且数据都是通过适配器加载的。RecyclerView的功能更加强大,接下来我们从以下几个方面来分析:

[外链图片转存中…(img-dYgKBe6V-1645971864933)]

2.5 实战演练—动物列表

​ 接下来,我们通过一个案例来讲解如何通过RecyclerView控件显示一个动物列表界面。本案例的界面效果如下图所示。

[外链图片转存中…(img-Jttw8iID-1645971864934)]

reslayoutactivity_main.xml下放置界面控件



    
    

reslayoutrecycler_item.xml创建列表条目



    
    
        
        
    

RecyclerviewMainActivity.java下实现界面显示功能

package cn.itcast.recyclerview;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private HomeAdapter mAdapter;
    private String[] names = {"小猫", "哈士奇", "小黄鸭", "小鹿", "老虎"};
    private int[] icons = {R.drawable.cat, R.drawable.siberianhusky,
            R.drawable.yellowduck, R.drawable.fawn, R.drawable.tiger};
    private String[] introduces = {
            "猫,属于猫科动物,分家猫、野猫,是全世界家庭中较为广泛的宠物。",
            "西伯利亚雪橇犬,常见别名哈士奇,昵称为二哈。",
            "鸭的体型相对较小,颈短,一些属的嘴要大些。腿位于身体后方,因而步态蹒跚。",
            "鹿科是哺乳纲偶蹄目下的一科动物。体型大小不等,为有角的反刍类。",
            "虎,大型猫科动物;毛色浅黄或棕黄色,满有黑色横纹;头圆、耳短,耳背面黑色,中央有一白斑甚显著;四肢健壮有力;尾粗长,具黑色环纹,尾端黑色。"
    };
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView = findViewById(R.id.id_recyclerview);
        //设置RecyclerView控件的显示方式为线性垂直
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new HomeAdapter();
        //将HomeAdapter对象设置到RecyclerView控件上
        mRecyclerView.setAdapter(mAdapter);
    }
    
    
    class HomeAdapter extends RecyclerView.Adapter {
        @Override
        //加载item界面的布局文件,并将MyViewHolder类的对象返回
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            MyViewHolder holder = new MyViewHolder(LayoutInflater.from(MainActivity.this).inflate(
                    R.layout.recycler_item, parent, false));
            return holder;
        }

        @Override
        //将获取的数据设置到对应的控件上
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.name.setText(names[position]);
            holder.iv.setImageResource(icons[position]);
            holder.introduce.setText(introduces[position]);
        }
        
        @Override
        //获取列表条目的总数
        public int getItemCount() {
            return names.length;
        }
        class MyViewHolder extends RecyclerView.ViewHolder {
            TextView name;
            ImageView iv;
            TextView introduce;
            //获取item界面上的控件
            public MyViewHolder(View view) {
                super(view);
                name = view.findViewById(R.id.name);
                iv = view.findViewById(R.id.iv);
                introduce = view.findViewById(R.id.introduce);
            }
        }
    }
}
2.5 实战演练—仿今日头条

​ 接下来以仿今日头条推荐列表为例,来演示如何使用RecyclerView控件,仿今日头条推荐列表界面的效果如下图所示。

[外链图片转存中…(img-pdHqh5Oy-1645971864935)]

[外链图片转存中…(img-ps9RF6fE-1645971864936)]

resvaluesstyles.xml创建样式



    
    
    
    
    


resvaluescolors.xml添加颜色值



    #008577
    #00574B
    #D81B60
    #eeeeee
    #828282

reslayouttitle_bar.xml创建标题栏



    
    

reslayoutactivity_main.xml搭建推荐列表界面



    
    
        
        
        
        
        
        
        
    
    
    

reslayoutlist_item_one/two.xml搭建列表条目界面



    
        
        
            
            
                
                
                
            
        
    
    



    
    
        
        
        
    
    
        
            
            
            
        
    

headlineMainActivity.java 显示推荐列表的数据

package cn.itcast.headline;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

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

public class MainActivity extends AppCompatActivity {
    private String[] titles = {"各地餐企齐行动,杜绝餐饮浪费",
            "花菜有人焯水,有人直接炒,都错了,看饭店大厨如何做",
            "睡觉时,双脚突然蹬一下,有踩空感,像从高楼坠落,是咋回事?",
            "实拍外卖小哥砸开小吃店的卷帘门救火,灭火后淡定继续送外卖",
            "还没成熟就被迫提前采摘,8毛一斤却没人要,果农无奈:不摘不行",
            "大会、大展、大赛一起来,北京电竞“好嗨哟”"};
    private String[] names = {"央视新闻客户端", "味美食记", "民富康健康", "生活小记",
            "禾木报告", "燕鸣"};
    private String[] comments = {"9884评", "18评", "78评", "678评", "189评",
            "304评"};
    private String[] times = {"6小时前", "刚刚", "1小时前", "2小时前", "3小时前",
            "4个小时前"};
    private int[] icons1 = {R.drawable.food, R.drawable.takeout,
            R.drawable.e_sports};
    private int[] icons2 = {R.drawable.sleep1, R.drawable.sleep2, R.drawable.sleep3,
            R.drawable.fruit1,R.drawable.fruit2, R.drawable.fruit3};
    //新闻类型,1表示置顶新闻或只有1张图片的新闻,2表示包含3张图片的新闻
    private int[] types = {1, 1, 2, 1, 2, 1};
    private RecyclerView mRecyclerView;
    private NewsAdapter mAdapter;
    private List NewsList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setData();
        mRecyclerView = findViewById(R.id.rv_list);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new NewsAdapter(MainActivity.this, NewsList);
        mRecyclerView.setAdapter(mAdapter);
    }
//    将定义的数组中的数据添加到新闻数据集合NewList中
    private void setData() {
        NewsList = new ArrayList();
        NewsBean bean;
        for (int i = 0; i < titles.length; i++) {
            bean = new NewsBean();
            bean.setId(i + 1);
            bean.setTitle(titles[i]);
            bean.setName(names[i]);
            bean.setComment(comments[i]);
            bean.setTime(times[i]);
            bean.setType(types[i]);
            switch (i) {
                case 0: //置顶新闻的图片设置
                    List imgList0 = new ArrayList<>();
                    bean.setImgList(imgList0);
                    break;
                case 1://设置第2个条目的图片数据
                    List imgList1 = new ArrayList<>();
                    imgList1.add(icons1[i - 1]);
                    bean.setImgList(imgList1);
                    break;
                case 2://设置第3个条目的图片数据
                    List imgList2 = new ArrayList<>();
                    imgList2.add(icons2[i - 2]);
                    imgList2.add(icons2[i - 1]);
                    imgList2.add(icons2[i]);
                    bean.setImgList(imgList2);
                    break;
                case 3://设置第4个条目的图片数据
                    List imgList3 = new ArrayList<>();
                    imgList3.add(icons1[i - 2]);
                    bean.setImgList(imgList3);
                    break;
                case 4://设置第5个条目的图片数据
                    List imgList4 = new ArrayList<>();
                    imgList4.add(icons2[i - 1]);
                    imgList4.add(icons2[i]);
                    imgList4.add(icons2[i + 1]);
                    bean.setImgList(imgList4);
                    break;
                case 5://设置第6个条目的图片数据
                    List imgList5 = new ArrayList<>();
                    imgList5.add(icons1[i - 3]);
                    bean.setImgList(imgList5);
                    break;
            }
            NewsList.add(bean);
        }
    }
}

headlineNewsAdapter.java 创建适配器NewsAdapter

package cn.itcast.headline;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class NewsAdapter extends RecyclerView.Adapter {
    private Context mContext;
    private List NewsList;
    public NewsAdapter(Context context,List NewsList) {
        this.mContext = context;
        this.NewsList=NewsList;
    }
    //加载条目视图
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
                                                      int viewType) {
        View itemView=null;
        RecyclerView.ViewHolder holder=null;
        if (viewType == 1){
            itemView = LayoutInflater.from(mContext).inflate(R.layout.
                    list_item_one, parent, false);
            holder= new MyViewHolder1(itemView);
        }else if (viewType == 2){
            itemView = LayoutInflater.from(mContext).inflate(R.layout.
                    list_item_two, parent, false);
            holder= new MyViewHolder2(itemView);
        }
        return holder;
    }
//    获取条目类型
    @Override
    public int getItemViewType(int position) {
        return NewsList.get(position).getType();
    }
//    绑定界面数据
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder,
                                 int position) {
        NewsBean bean=NewsList.get(position);
        if (holder instanceof MyViewHolder1){
            if (position==0) {
                ((MyViewHolder1) holder).iv_top.setVisibility(View.VISIBLE);
                ((MyViewHolder1) holder).iv_img.setVisibility(View.GONE);
            } else {
                ((MyViewHolder1) holder).iv_top.setVisibility(View.GONE);
                ((MyViewHolder1) holder).iv_img.setVisibility(View.VISIBLE);
            }
            ((MyViewHolder1) holder).title.setText(bean.getTitle());
            ((MyViewHolder1) holder).name.setText(bean.getName());
            ((MyViewHolder1) holder).comment.setText(bean.getComment());
            ((MyViewHolder1) holder).time.setText(bean.getTime());
            if (bean.getImgList().size()==0)return;
            ((MyViewHolder1) holder).iv_img.setImageResource(bean.getImgList()
                    .get(0));
        }else if (holder instanceof MyViewHolder2){
            ((MyViewHolder2) holder).title.setText(bean.getTitle());
            ((MyViewHolder2) holder).name.setText(bean.getName());
            ((MyViewHolder2) holder).comment.setText(bean.getComment());
            ((MyViewHolder2) holder).time.setText(bean.getTime());
            ((MyViewHolder2) holder).iv_img1.setImageResource(bean.getImgList()
                    .get(0));
            ((MyViewHolder2) holder).iv_img2.setImageResource(bean.getImgList()
                    .get(1));
            ((MyViewHolder2) holder).iv_img3.setImageResource(bean.getImgList()
                    .get(2));
        }
    }
//    获取条目总数
    @Override
    public int getItemCount() {
        return NewsList.size();
    }
    class MyViewHolder1 extends RecyclerView.ViewHolder {
        ImageView iv_top,iv_img;
        TextView title,name,comment,time;
        public MyViewHolder1(View view) {
            super(view);
            iv_top = view.findViewById(R.id.iv_top);
            iv_img = view.findViewById(R.id.iv_img);
            title = view.findViewById(R.id.tv_title);
            name = view.findViewById(R.id.tv_name);
            comment = view.findViewById(R.id.tv_comment);
            time = view.findViewById(R.id.tv_time);
        }
    }
    class MyViewHolder2 extends RecyclerView.ViewHolder {
        ImageView iv_img1,iv_img2,iv_img3;
        TextView title,name,comment,time;
        public MyViewHolder2(View view) {
            super(view);
            iv_img1 = view.findViewById(R.id.iv_img1);
            iv_img2 = view.findViewById(R.id.iv_img2);
            iv_img3 = view.findViewById(R.id.iv_img3);
            title = view.findViewById(R.id.tv_title);
            name = view.findViewById(R.id.tv_name);
            comment = view.findViewById(R.id.tv_comment);
            time = view.findViewById(R.id.tv_time);
        }
    }
}

headlineNewsBean.java 封装新闻信息实体类,在该类中创建新闻信息属性对应的字段

package cn.itcast.headline;
import java.util.List;
public class NewsBean {
    private int id;                   //新闻id
    private String title;            //新闻标题
    private List imgList; //新闻图片
    private String name;             //用户名
    private String comment;         //用户评论
    private String time;             //新闻发布时间
    private int type;                 //新闻类型
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getComment() {
        return comment;
    }
    public void setComment(String comment) {
        this.comment = comment;
    }
    public String getTime() {
        return time;
    }
    public void setTime(String time) {
        this.time = time;
    }
    public List getImgList() {
        return imgList;
    }
    public void setImgList(List imgList) {
        this.imgList = imgList;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
}
三、自定义控件 目标

掌握自定义View中的3个方法,能够在界面中绘制一个圆形图案

​ 通常开发Android应用的界面时,使用的控件都不直接使用View,而是使用View的子类。虽然Android系统中提供了很多继承View类的控件,但是在实际开发中,还会出现不满足需求的情况。此时我们可以通过自定义View的方式进行实现。

​ 当使用系统控件不满足需求时,需要自定义控件。最简单的自定义View就是创建一个类继承自View类或者其子类,并重写该类的构造方法。示例代码如下:

   public class Customview extends View{
       //在Java代码中创建对象时,使用该构造函数
       public Customview(Context context) {
            super(context);
       }
       //在XML布局中引入自定义控件时,使用该构造函数
       public Customview(Context context, AttributeSet attrs) {
            super(context, attrs);
       }
}

​ 由于系统自带的控件不能满足需求中的某种样式或功能,所以我们需要在自定义View中通过重写指定的方法来添加额外的样式和功能。

[外链图片转存中…(img-myjo4aVl-1645971864936)]

​ 接下来,我们通过一个案例讲解如何使用自定义View在界面中显示一个圆形,显示圆形界面的效果如下图所示。

customviewCircleView.java自定义CircleView类

package cn.itcast.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View {
    public CircleView(Context context) {
        super(context);
    }
    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int r = getMeasuredWidth() / 2;
        int centerX = getLeft() + r;
        int centerY = getTop()+ r;
        Paint paint = new2 Paint();
        paint.setColor(Color.RED);
        //开始绘制
        canvas.drawCircle(centerX, centerY, r, paint);
    }
}

reslayoutactivity_main.xml引用自定义控件CustomView



    

alertDialog对话框

ew extends View{
//在Java代码中创建对象时,使用该构造函数
public Customview(Context context) {
super(context);
}
//在XML布局中引入自定义控件时,使用该构造函数
public Customview(Context context, AttributeSet attrs) {
super(context, attrs);
}
}

​		由于系统自带的控件不能满足需求中的某种样式或功能,所以我们需要在自定义View中通过重写指定的方法来添加额外的样式和功能。

[外链图片转存中...(img-myjo4aVl-1645971864936)]



​		接下来,我们通过一个案例讲解如何使用自定义View在界面中显示一个圆形,显示圆形界面的效果如下图所示。

[外链图片转存中...(img-cGVS3ZDb-1645971864937)]



customviewCircleView.java`自定义CircleView类`

```java
package cn.itcast.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View {
    public CircleView(Context context) {
        super(context);
    }
    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int r = getMeasuredWidth() / 2;
        int centerX = getLeft() + r;
        int centerY = getTop()+ r;
        Paint paint = new2 Paint();
        paint.setColor(Color.RED);
        //开始绘制
        canvas.drawCircle(centerX, centerY, r, paint);
    }
}

reslayoutactivity_main.xml引用自定义控件CustomView



    

alertDialog对话框

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/750272.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号