首页 > 其他分享 >Android开发基础:AdapterView类视图控件的使用,Fragment,ViewPager2视图控件的使用

Android开发基础:AdapterView类视图控件的使用,Fragment,ViewPager2视图控件的使用

时间:2024-04-08 13:29:55浏览次数:31  
标签:控件 Fragment Adapter list 视图 new public

目录

一,Adapter

1.什么是Adapter?

 2.Android中的常用Adapter

二,AdapterView

1.AdapterView简介

 2.AdapterView的子视图对象 

三,ListView滑动列表形式

四, GridView网格形式显示

 五,Fragment和ViewPager2视图控件的使用

1.什么是Fragment?

2.ViewPager2

3.TabLayout+ViewPager2+Fragment实现微信滑动界面


一,Adapter

1.什么是Adapter?

        Adapter(适配器)是连接后端数据与前端视图的接口,是数据与视图之间交互的中介。众所周知,Android用户界面采用MVC框架,即model-view-controller,model和view可理解为是数据和视图,而Adapter就属于中间的controller部分。

        用Adapter作为数据和视图之间交互的中介,就可以将这两部分分开操作:数据改变时,不需要修改视图组件,只需更新Adapter;视图组件改变时,不需要修改数据,只需绑定Adapter即可。

 2.Android中的常用Adapter

  1. BaseAdapter:用于自定义适配器,数据源由用户决定,使用时会被继承并重写方法,最常用也是最灵活的一个adapter;
  2. ArrayAdapter:最简单的适配器,数据源为文本字符,只能显示一行文本;
  3. SimpleAdapter:简单适配器,数据源结构比较复杂,一般为List<Map>类型对象;
  4. SimpleCursorAdapter:游标适配器,用于显示简单文本类型的listview,数据源一般为数据库中的数据;

二,AdapterView

1.AdapterView简介

        AdapterView:容器控件,整体由一个个子元素item组成,子元素的内容与数据由Adapter决定。如下图所示:整体容器框架是AdapterView,其中的每个小元素就是item。

 2.AdapterView的子视图对象 

ListView以垂直滑动列表形式显示一组数据。
GridView以网格形式显示一组数据。
Spinner以下拉列表形式显示一组数据。

三,ListView滑动列表形式

ListView:以垂直可滑动列表形式显示子项目的视图容器,如下图所示:

 ListView使用的基本流程(实现简单的微信界面):

(1)准备ListView整体布局以及每一个子项的视图布局(可以使用内置的布局,也可以自定义布局,我们这里使用自定义布局):

整体布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
   <ListView
       android:id="@+id/lv_wechat"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:visibility="invisible">
   </ListView>
</RelativeLayout>

子元素布局(头像+昵称+聊天信息): 

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

    <ImageView
        android:id="@+id/iv_avatar1"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:src="@mipmap/liyue"
        >
    </ImageView>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="5"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:id="@+id/tv_nickname1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="璃月"
            ></TextView>
        <TextView
            android:id="@+id/tv_endmessage1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="10sp"
            android:text="114514"
            ></TextView>
    </LinearLayout>

</LinearLayout>

效果预览:

(2)创建Adapter(连接数据源和子元素视图布局,这里使用继承BaseAdapter的自定义适配器):

public class PracticeAdapter extends BaseAdapter {

    private Context context; //上下文
    private Integer layoutId; //布局子控件id
    private List<Practice> list; //数据源

    public PracticeAdapter(){}
    //构造器
    public PracticeAdapter(Context context, Integer layoutId, List<Practice> list){
        this.context = context;
        this.layoutId = layoutId;
        this.list = list;
    }
    //继承BaseAdapter需重写的四个方法
    public int getCount() {return list.size();}//数据个数
    public Object getItem(int position) {return list.get(position);}//对应位置的item
    public long getItemId(int position) {return position;}//返回item下标位置
    //getView最重要的一个函数,position当前item的下标,convertView当前的视图,parent当前视图的父视图
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null){
            convertView = LayoutInflater.from(context).inflate(layoutId, null);
        }
        //获取列表项中的控件
        ImageView iv_avatar1 = convertView.findViewById(R.id.iv_avatar1);
        TextView tv_nickname1 = convertView.findViewById(R.id.tv_nickname1);
        TextView tv_endmessage1 = convertView.findViewById(R.id.tv_endmessage1);
        //给数据项填充数据
        Practice practice = list.get(position);
        iv_avatar1.setImageResource(practice.getAvatar());
        tv_nickname1.setText(practice.getNickName());
        tv_endmessage1.setText(practice.getEndMessage());
        //返回列表项
        return convertView;
    }
}

 为Adapter准备数据源:

public class Practice {
    private Integer avatar;//头像
    private String nickName;//昵称
    private String endMessage;//聊天信息

    public Practice(){}
    //构造器
    public Practice(Integer avatar, String nickName, String endMessage){
        this.avatar = avatar;
        this.nickName = nickName;
        this.endMessage = endMessage;
    }
    //数据源 包括头像,昵称,聊天信息
    public static List<Practice> getPractice(){
        List<Practice> list = new ArrayList<>();
        list.add(new Practice(R.mipmap.liyue, "cxk", "师傅!救我口牙!"));
        list.add(new Practice(R.mipmap.liyue, "cxk1", "2333333"));
        list.add(new Practice(R.mipmap.liyue, "cxk2", "[语音聊天]"));
        return list;
    }
}

(3)为ListView绑定Adapter:

//获取ListView控件
ListView lv_practice = findViewById(R.id.lv_practice);
//获取数据源
List<Practice> list = Practice.getPractice();
//创建Adapter
PracticeAdapter adapter = new PracticeAdapter(
         TabPracticeActivity.this,
         R.layout.item_practice, //子控件id
         list
);
//为ListView绑定Adapter
lv_practice.setAdapter(adapter);

(4)为ListView绑定事件监听器:

//使用匿名内部类的方式绑定事件监听器
lv_practice.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Toast.makeText(
            TabPracticeActivity.this, 
            list.get(position).getNickName(), 
            Toast.LENGTH_SHORT
        ).show();
    }
});

最终效果:

四, GridView网格形式显示

GridView:以网格形式显示子项目的视图容器:

GridView使用的基本流程:

GridView使用的流程与ListView基本一致,同样分为四步:

  1. 准备GridView每一个子项的视图布局。( 可以使用内置的布局,也可以用户自定义布局);
  2. 创建Adapter(连接数据源和视图布局);
  3. 为GridView绑定Adapter;
  4. 为GridView绑定事件监听器;

 在这里我们可以直接将上面ListView的Adapter绑定给GridView,也就是同一份数据对应不同的视图。首先需要将布局文件中的ListView换成GridView:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
   <GridView
        android:id="@+id/gv_product"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:horizontalSpacing="2dp"
        android:verticalSpacing="2dp"
        android:numColumns="2">
    </GridView>
</RelativeLayout>

然后将上面步骤三四中的ListView全部换成GridView即可:

//获取GridView控件
GridView gv_product = findViewById(R.id.gv_product);
//获取数据源
List<Practice> list = Practice.getPractice();
//创建适配器
PracticeAdapter adapter = new PracticeAdapter(
    TabPracticeActivity.this,
    R.layout.item_practice, //子控件id
    list
);
//绑定适配器
gv_product.setAdapter(adapter);
//设置事件监听器
gv_product.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Toast.makeText(
            TabPracticeActivity.this, 
            list.get(position).getNickName(),                                                     
            Toast.LENGTH_SHORT
        ).show();
    }
});

最终效果如下,可以看到滑动列表效果变为了网格形式效果:

 

 五,Fragment和ViewPager2视图控件的使用

1.什么是Fragment?

        Fragment意为”片段“,是为了解决安卓app运行的设备大小不一而提出的,Fragment将屏幕分成了几组,进行模块化管理,可以将Fragment当成Activity界面的一个组成部分,一个Activity可以包含很多Fragment。

        Fragment拥有自己的生命周期,可接收、处理用户的事件。 Activity中可以动态的添加、替换和移除某个Fragment。

2.ViewPager2

        ViewPager2(视图控件)基于RecycleView实现,可以实现类似抖音的上下滑动,也可以实现左右滑动,通常配合Fragment一起使用,需要借助FragmentStateAdapter,从而将Fragment和Activity关联在一起。

3.TabLayout+ViewPager2+Fragment实现微信滑动界面

        使用TabLayout可以实现微信底部导航栏,但是界面之间的跳转只能是点击跳转,如果想要实现滑动跳转效果,需要使用ViewPager2+Fragment,因为点击跳转时,两个界面不会同时出现,使用事件监听器设置View是否显示就可实现,但滑动跳转时,两个界面会同时存在。因此需要ViewPager2和Fragment一起使用。

具体实现步骤如下:

(1)设计布局文件(TabLayout+ViewPager2):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/vp_context"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </androidx.viewpager2.widget.ViewPager2>

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tb_nav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">
    </com.google.android.material.tabs.TabLayout>

</RelativeLayout>

(2)定义Fragment的item子布局(取名fragment_wechat)以及对应的Fragment,因为微信界面有四个(微信,通讯录,发现,我的),因此item子布局和对应的Fragment也要定义四个(实际开发中由四个人分别定义):

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="微信界面"
        android:textSize="60sp">
    </TextView>

</LinearLayout>
public class WechatFragment extends Fragment {
    @Nullable
    @Override
    //inflater布局加载器 container是否为父子容器 savedInstanceState保存实例状态
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_wechat, null);
        return view;
    }
}

(3)自定义FragmentStateAdapter,联系Fragment和Activity:

public class WechatFragmentAdapter extends FragmentStateAdapter {

    private List<Fragment> fragmentList;//Fragment数据源,存放定义的四个Fragment

    public WechatFragmentAdapter(List<Fragment> fragmentList, @NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);//调用Activity,因为Fragment最终必须要和Activity联系,因此构造器必须实现;
        this.fragmentList = fragmentList;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {return fragmentList.get(position);}
    @Override
    public int getItemCount() {return fragmentList.size();}
}

(4)给ViewPager2设定适配器:

//获取activity中的控件
TabLayout tb_nav = findViewById(R.id.tb_nav);
ViewPager2 vp_context = findViewById(R.id.vp_context);
//创建fragment数据源
List<Fragment> fragmentList = new ArrayList<>();
fragmentList.add(new WechatFragment());
fragmentList.add(new ContractFragment());
fragmentList.add(new FindFragment());
fragmentList.add(new MineFragment());
//创建适配器
WechatFragmentAdapter adapter = new WechatFragmentAdapter(
    fragmentList, this
);
//viewpager2绑定适配器
vp_context.setAdapter(adapter);

(5)关联TabLayout与ViewPager2(使用TabLayoutMediator):

//TabLayout和ViewPager2关联 通过TabLayoutMediator
TabLayoutMediator mediator = new TabLayoutMediator(
    tb_nav,//TabLayout
    vp_context,//ViewPager2
    new TabLayoutMediator.TabConfigurationStrategy() {
        @Override
        //设置每个tab位置的属性(图标,名称等)
        public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
            switch(position){
                case 0:
                    tab.setText("微信");
                    tab.setIcon(R.mipmap.message);
                    break;
                case 1:
                    tab.setText("联系人");
                    tab.setIcon(R.mipmap.contract);
                    break;
                case 2:
                    tab.setText("发现");
                    tab.setIcon(R.mipmap.find);
                    break;
                case 3:
                    tab.setText("我的");
                    tab.setIcon(R.mipmap.mine);
                    break;
            }
        }
    }
);
//使效果生效
mediator.attach();

最终效果如下:

标签:控件,Fragment,Adapter,list,视图,new,public
From: https://blog.csdn.net/IH_LZH/article/details/137432483

相关文章

  • 抢先看!界面控件DevExpress WPF 2024产品路线图预览(二)
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。本文将介绍2024年DevExpressWPF第一个主要更新(v2......
  • VS+QT编程找不到新增UI文件控件对象的问题
    转载自:VS写Qt项目时,ui界面拖拽的控件代码找不到引用的解决办法_vsqt中ui下的组件没有-CSDN博客1.保存Ui文件在拖拽控件之后,Ctrl+S2.重新编译ui文件鼠标右键选择要编译的UI文件,找到编译 3.右键项目,重新扫描解决方案 ......
  • Django框架之视图层
    一、三板斧的原理介绍1、HttpResponse在Django中,HttpResponse是一个类,用于构建HTTP响应并返回给客户端。当视图函数处理完请求后,需要返回一个响应时,就会使用HttpResponse对象。(1)创建HttpResponse对象fromdjango.httpimportHttpResponseresponse=HttpResponse(content="......
  • Halcon的HWindowControl控件在C#WinForm中的使用介绍(包括绘制ROI)
    Halcon的HSmartWindowControl控件在C#WinForm中的使用介绍(包括绘制ROI)文章目录Halcon的HSmartWindowControl控件在C#WinForm中的使用介绍(包括绘制ROI)一、引入hSmartWindowControl控件二、编写打开图像功能三、编写绘制ROI功能四、源程序下载Halcon的新版本中增加......
  • 往 VisualStudio 工具箱中添加 WPF/WinForms 控件的几种方式
    在使用VisualStudio开发WPF或WinForms应用时,打开UI文件的设计界面,我们可以从工具箱的控件列表中直接拖拽控件到界面上。通过这种方式,可以清晰的展示控件库中所有可用的控件,并且非常方便的将其添加到界面中。那么我们可以通过哪些方式将WPF/WinForms控件库中的控件添加到VisualS......
  • QFComponent for lazarus增加新控件TQFGridPanelComponent
    TQFGridPanelComponent控件支持在单元格绑定可视控件,运行时单元格绑定的控件会吸附到相应的单元格里。|姓名|[#][C2]单位|办公地址|备注||:-:|:-:|:-:|:-:||秋风6|[bm4]检测中心1|南山建工村1|||秋风7|检测中心2|<COMPNAME=name3>[#][c4]南山建工村2|||[c2]地址|<COMPNAME=n......
  • ASP.NET中button、linkbutton、imagebutton及hyperlink这四个控件之间的功能区别?
    原文链接:https://blog.csdn.net/weixin_45763353/article/details/118005453Button是按钮控件,具有按钮所有的属性和事件方法,在客户端被渲染为表单元素提交按钮。Linkbutton是链接按钮,用于创建超链接样式的按钮。该控件的外观与HyperLink控件相同,但其功能与Button控件一样。它......
  • WPF布局控件汇总
    1.Grid表格布局Grid为WPF中最常用的布局容器,作为View中的主要组成部分,负责框架中整体的页面布局。注意:Grid的列宽与行高可采用固定、自动、按比例三种方式定义。固定长度:值为一个确定的数字自动长度:值为Auto,实际作用就是取实际控件所需的最小值比例长度:*表示占用剩余的全......
  • AndroidStudio学习记录(4):单选按钮控件RadioButton
    用于应用二选一等多选选项的设置<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">&l......
  • WPF开发一个可以自适应排列的Panel控件
    一.控件介绍    初看标题可能无法理解,我们看看什么是自适应排列。乍一看它有点像WrapPanel控件,都是从左至右排列,如果一行排列不下就换行继续排列,但是细看你就会发现不对,WrapPanel控件行尾是不会对齐的,也就是说只要WrapPanel的子控件的宽度不一致,每一行的末尾就会必定留下一......