Android回收视图

news2024/11/30 10:45:14

本文所有代码均存放于https://github.com/MADMAX110/BitsandPizzas
回收视图是列表视图的一个更高级也更灵活的版本。
回收视图比列表视图更加灵活,所以需要更多设置,回收视图使用一个适配器访问它的数据,不过与列表视图不同,回收视图不使用数组适配器之类的内置Android适配器。你必须编写你自己的适配器,要根据数据适当裁剪。这包括指定的数据的类型,创建视图并把视图绑定到视图。
另外要使用一个布局管理器将数据项放置在回收视图中,有很多内置的布局管理器可以使用,可以把数据项放在一个线性列表或网格中。
回到之前的披萨应用,使用回收视图共需要五个步骤:
1、为工程增加披萨数据
2、为披萨数据创建一个卡片视图
3、创建一个回收视图适配器
4、向PizzaFragment增加一个回收视图
5、让回收视图响应单击

一、增加披萨数据

将以下图片加入工程的drawable文件夹,分别命名为funghi和diavolo。
在这里插入图片描述
在这里插入图片描述
在com.hfad.bitsandpizzas包中新建Pizza类:

package com.hfad.bitsandpizzas;

public class Pizza {
    private String name;
    private int imageResourceId;

    public static final Pizza[] pizzas = {
            new Pizza("Diavolo", R.drawable.diavolo),
            new Pizza("Funghi", R.drawable.funghi)
    };

    private Pizza(String name, int imageResourceId) {
        this.name = name;
        this.imageResourceId = imageResourceId;
    }

    public String getName() {
        return name;
    }

    public int getImageResourceId() {
        return imageResourceId;
    }
}

二、创建卡片视图

卡片视图是一种帧布局,允许在虚拟卡片上显示信息。卡片视图有圆角和阴影,使它看上去就像放在背景之上。如果为我们的披萨数据使用卡片视图,每个披萨看上去就像显示在回收视图中的一个单独的卡片中。
要创建一个卡片视图,需要向布局增加一个< CardView >元素。如果想在回收视图中使用卡片视图。需要为卡片视图创建一个新的布局文件,在layout文件夹中新建一个名为card_captioned_image的视图。

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_margin="4dp"
    card_view:cardElevation="2dp"
    card_view:cardCornerRadius="4dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ImageView
            android:id = "@+id/info_image"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1.0"
            android:scaleType="centerCrop"/>

        <TextView
            android:id="@+id/info_text"
            android:layout_marginBottom="4dp"
            android:layout_marginLeft="4dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</androidx.cardview.widget.CardView>

三、创建回收视图适配器

使用回收视图时,需要创建一个回收视图适配器,与列表视图不同,回收视图不使用Android自带的内置适配器。
适配器有两个主要任务:在回收视图中创建各个可见的视图,并把各个视图绑定到一个数据。
在com.hfad.bitsandpizzas包中新建一个名为CaptionedImagesAdapter的Java类。

package com.hfad.bitsandpizzas;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;

public class CaptionedImagesAdapter extends RecyclerView.Adapter<CaptionedImagesAdapter.ViewHolder> {

    private String[] captions;
    private int[] imageIds;
    public static class ViewHolder extends RecyclerView.ViewHolder{
        //每个ViewHolder包含一个CardView
        private CardView cardView;
        public ViewHolder(CardView v) {
            super(v);
            cardView = v;
        }
    }

    //使用适配器的构造方法向它传递数据
    public CaptionedImagesAdapter(String[] captions, int[] imageIds){
        this.captions = captions;
        this.imageIds = imageIds;
    }

    //告诉适配器有多少个数据项
    public int getItemCount() {
        return captions.length;
    }

    CaptionedImagesAdapter.ViewHolder onCreateViewHo;

    @NonNull
    @Override
    //为CardViews使用前面创建的布局
    //回收视图需要新的视图持有者时就会调用该方法
    //首次构造回收视图时,回收视图会反复调用这个方法来构造将在屏幕上显示的一组持有者
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        CardView cv = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.card_captioned_image, parent, false);
        return new ViewHolder(cv);
    }

    //用数据填充CardView的ImageView和TextView
    public void onBindViewHolder(ViewHolder holder, int position){
        CardView cardView = holder.cardView;
        ImageView imageView = (ImageView) cardView.findViewById(R.id.info_image);
        Drawable drawable = ContextCompat.getDrawable(cardView.getContext(), imageIds[position]);
        imageView.setImageDrawable(drawable);
        imageView.setContentDescription(captions[position]);
        TextView textView = (TextView) cardView.findViewById(R.id.info_text);
        textView.setText(captions[position]);
    }
}

四、创建回收视图

创建回收视图,会把披萨数据传递给适配器,使适配器能够用披萨图像和图像填充卡片,然后这个回收视图再显示这个卡片,还要把这个回收视图增加到PizzaFragment中。只要用户单击了MainActivity中的Pizzas标签页,就会显示披萨。
新增一个fragment_pizza.xml布局,只需要显示一个回收视图即可。

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pizza_recycle"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical">
</androidx.recyclerview.widget.RecyclerView>

更新PizzaFragment让回收视图使用适配器。
回收视图使用一个布局管理器排列视图,可以选择使用线性列表、网格和不规则网格显示视图。

package com.hfad.bitsandpizzas;

import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class PizzaFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        RecyclerView pizzaRecycle = (RecyclerView) inflater.inflate(
                R.layout.fragment_pizza, container, false);
        String[] pizzaNames = new String[Pizza.pizzas.length];
        for (int i = 0; i < pizzaNames.length; i++){
            pizzaNames[i] = Pizza.pizzas[i].getName();
        }
        int[] pizzasImages = new int[Pizza.pizzas.length];
        for (int i = 0; i < pizzaNames.length; i++){
            pizzasImages[i] = Pizza.pizzas[i].getImageResourceId();
        }
        CaptionedImagesAdapter adapter = new CaptionedImagesAdapter(pizzaNames, pizzasImages);
        pizzaRecycle.setAdapter(adapter);
        //在一个两列的网格中显示卡片视图
        GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
        pizzaRecycle.setLayoutManager(layoutManager);
        return pizzaRecycle;
    }
}

试一试应用效果如图:
在这里插入图片描述

五、让回收视图响应单击

创建一个新活动PizzaDetailActivity,用户单击某个披萨时就会启动这个活动。其布局名为activity_pizza_detail。

<?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"
    tools:context=".PizzaDetailActivity">

    <include
        layout="@layout/toolbar_main"
        android:id="@+id/toolbar" />

    <TextView
        android:id="@+id/pizza_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"/>

    <ImageView
        android:id="@+id/pizza_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"/>

</LinearLayout>

更新AndroidManifest.xml为PizzaDetailActivity指定一个父活动。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.BitsAndPizzas"
        tools:targetApi="31">

        <meta-data
            android:name="com.google.android.actions"
            android:resource="@menu/menu_main" />

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".OrderActivity"
            android:label="@string/create_order"
            android:parentActivityName=".MainActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>
        <activity android:name=".PizzaDetailActivity"
            android:parentActivityName=".MainActivity">
        </activity>
    </application>

</manifest>

更新PizzaDetailActivity.java代码

package com.hfad.bitsandpizzas;

import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;

public class PizzaDetailActivity extends AppCompatActivity {
    public static final String EXTRA_PIZZA_ID = "pizzaId";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pizza_detail);

        //Set the toolbar as the activity's app bar
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);

        //Display details of the pizza
        int pizzaId = (Integer)getIntent().getExtras().get(EXTRA_PIZZA_ID);
        String pizzaName = Pizza.pizzas[pizzaId].getName();
        TextView textView = (TextView)findViewById(R.id.pizza_text);
        textView.setText(pizzaName);
        int pizzaImage = Pizza.pizzas[pizzaId].getImageResourceId();
        ImageView imageView = (ImageView)findViewById(R.id.pizza_image);
        imageView.setImageDrawable(ContextCompat.getDrawable(this, pizzaImage));
        imageView.setContentDescription(pizzaName);
    }
}

更新PizzaFragment.java

package com.hfad.bitsandpizzas;

import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class PizzaFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        RecyclerView pizzaRecycle = (RecyclerView) inflater.inflate(
                R.layout.fragment_pizza, container, false);
        String[] pizzaNames = new String[Pizza.pizzas.length];
        for (int i = 0; i < pizzaNames.length; i++){
            pizzaNames[i] = Pizza.pizzas[i].getName();
        }
        int[] pizzasImages = new int[Pizza.pizzas.length];
        for (int i = 0; i < pizzaNames.length; i++){
            pizzasImages[i] = Pizza.pizzas[i].getImageResourceId();
        }
        CaptionedImagesAdapter adapter = new CaptionedImagesAdapter(pizzaNames, pizzasImages);
        pizzaRecycle.setAdapter(adapter);
        //在一个两列的网格中显示卡片视图
        GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
        pizzaRecycle.setLayoutManager(layoutManager);

        adapter.setListener(new CaptionedImagesAdapter.Listener() {
            @Override
            public void onCLick(int position) {
                Intent intent = new Intent(getActivity(), PizzaDetailActivity.class);
                intent.putExtra(PizzaDetailActivity.EXTRA_PIZZA_ID, position);
                getActivity().startActivity(intent);
            }
        });

        return pizzaRecycle;
    }
}

试一试
在这里插入图片描述
单击其中的选项后:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1051864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[RCTF2015]EasySQL 二次注入 regexp指定字段 reverse逆序输出

第一眼没看出来 我以为是伪造管理员 就先去测试管理员账号 去register.php 注册 首先先注册一个自己的账号 我喜欢用admin123 发现里面存在修改密码的内容 那么肯定链接到数据库了 题目又提示是sql 那我们看看能不能修改管理员密码 首先我们猜测闭合 通过用户名 admin…

HTML,CSS,JavaScript知识点

HTML&#xff0c;CSS&#xff0c;JavaScript知识点 HTML篇 HTML是超文本标记语言。文件以.html结尾。 Hello,HTML。常用的工具: 标题: <h1>一级标题</h1><h2>二级标题</h2><h3>三级标题</h3><h4>四级标题</h4>无序列表和有…

YOLOv8+swin_transfomer

测试环境&#xff1a;cuda11.3 pytorch1.11 rtx3090 wsl2 ubuntu20.04 本科在读&#xff0c;中九以上老师或者课题组捞捞我&#xff0c;孩子想读书&#xff0c;求课题组师兄内推qaq 踩了很多坑&#xff0c;网上很多博主的代码根本跑不通&#xff0c;自己去github仓库复现修…

PHP免登录积分商城系统/动力商城/积分商城兑换系统源码Tinkphp

介绍&#xff1a; PHP免登录积分商城系统/动力商城/积分商城兑换系统源码Tinkphp&#xff0c;这个免登录积分商城系统是一种新型的电子商务模式&#xff0c;它通过省去麻烦的注册步骤&#xff0c;让用户能够很快又方便去积分兑换。这种商城系统具有UI干净整洁大方、运行顺畅的…

正点原子嵌入式linux驱动开发——STM32MP1启动详解

STM32单片机是直接将程序下载到内部 Flash中&#xff0c;上电以后直接运行内部 Flash中的程序。 STM32MP157内部没有供用户使用的 Flash&#xff0c;系统都是存放在外部 Flash里面的&#xff0c;比如 EMMC、NAND等&#xff0c;因此 STM32MP157上电以后需要从外部 Flash加载程序…

Mendix中的依赖管理:npm和Maven的应用

序言 在传统java开发项目中&#xff0c;我们可以利用maven来管理jar包依赖&#xff0c;但在mendix项目开发Custom Java Action时&#xff0c;由于目录结构有一些差异&#xff0c;我们需要自行配置。同样的&#xff0c;在mendix项目开发Custom JavaScript Action时&#xff0c;…

调度算法2-适用于交互式系统

一、时间片轮转调度算法(RR) 1.算法思想 Round-Robin 公平、轮流地为各个进程服务&#xff0c;让每个进程在一定时间间隔内都可得到响应 2.算法规则 按照各进程到达就绪队列的顺序&#xff0c;轮流让各个进程执行一个时间片 响应比(等待时间要求服务时间)/要求服务时间 3…

http请求报错:406 Not Acceptable的解决办法

目录 应用场景 基本概念 解决方法 方法一&#xff1a; 方法二&#xff1a; 方法三&#xff1a; 应用场景 接口在返回结果集的时候出现了406的报错&#xff0c;但是返回String类型不会报错&#xff0c;正常返回。 基本概念 406 Not Acceptable是一个HTTP响应状态码&…

Vue+ElementUI实现动态树和表格数据的分页模糊查询

目录 前言 一、动态树的实现 1.数据表 2.编写后端controller层 3.定义前端发送请求路径 4.前端左侧动态树的编写 4.1.发送请求获取数据 4.2.遍历左侧菜单 5.实现左侧菜单点击展示右边内容 5.1.定义组件 5.2.定义组件与路由的对应关系 5.3.渲染组件内容 5.4.通过动态…

Spring整合第三方框架

目录 Spring整合第三方框架 加载外部properties文件 自定义命名空间解析原理 自定义命名空间总结和案例需求 总结 案例 Spring整合第三方框架 加载外部properties文件 Spring整合第三方框架不像MyBatis那么简单了&#xff0c;例如Dubbo框架在与Spring框架整合时&#xf…

苹果CMS插件-苹果CMS全套插件免费

网站内容的生成和管理对于网站所有者和内容创作者来说是一个挑战。有一些强大的工具可以帮助您轻松地解决这些问题。苹果CMS插件自动采集插件、采集发布插件以及采集伪原创发布插件&#xff0c;是这些工具之一。它们不仅可以极大地节省您的时间和精力&#xff0c;还可以提高您网…

Python编码规范与代码优化

博主&#xff1a;命运之光 专栏&#xff1a;Python程序设计 Python编码规范 Python的程序由包、模块&#xff08;即一个Python文件&#xff09;、函数、类和语句组成 (1) 命名规则 变量名、包名、模块名通常采用小写字母开头&#xff0c;如果名称中包含多个单词&#xff0c;一…

【Axure】Axure的常用功能

选择 分为相交选中和包含选中 相交选中&#xff1a;部分选中即是选中包含选中&#xff1a;全选才是选中 缩放 按住元件四角&#xff0c;等比例缩放 置顶和置底 所谓置于顶层就是不被后来的元件覆盖住&#xff0c;置于底层的意思则相反 组合、对齐、分布 组合&#xff1…

redis主从从,redis-7.0.13

redis主从从&#xff0c;redis-7.0.13 下载redis安装redis安装redis-7.0.13过程报错1、没有gcc&#xff0c;报错2、没有python3&#xff0c;报错3、[adlist.o] 错误 127 解决安装报错安装完成 部署redis 主从从结构redis主服务器配置redis启动redis登录redisredis默认是主 redi…

【CMU15-445 Part-13】Query Execution II

Part13-Query Execution II talk about how to execute with multiple workers TCO&#xff1a;Total Cost of Ownship Parallel VS. Distributed 区分数据库系统的并行执行和分布式数据库系统的分布式执行 数据库通过分散multiple resources 来改善数据库某些方面的性能 …

手动实现Transformer

Transformer和BERT可谓是LLM的基础模型&#xff0c;彻底搞懂极其必要。Transformer最初设想是作为文本翻译模型使用的&#xff0c;而BERT模型构建使用了Transformer的部分组件&#xff0c;如果理解了Transformer&#xff0c;则能很轻松地理解BERT。 一.Transformer模型架构 1…

css实现四角圆边框

摘要&#xff1a; 做大屏的项目时&#xff0c;遇到很多地方要用到不同尺寸的盒子需要圆角的效果&#xff0c;所以不可能要求ui弄那么多图片的&#xff0c;并且那么多图片加载速度很慢的&#xff0c;比较臃肿&#xff0c;大屏要求的就是流畅&#xff0c;所以这用css加载很快的&a…

基于Java的旅游管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

Linux系统下git相关使用

目录 git相关指令以及使用 什么是git Linux系统git功能的配置 关于码云的注册以及仓库的创建 git的相关指令 git clone 代码仓库地址 git add [文件名] git commit [文件名] -m "文件提交信息" git push git status 情况1&#xff1a;存在文件可以add 情况2&#xff…

KNN(下):数据分析 | 数据挖掘 | 十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…