【Android开发基础】说说模块设计(下拉刷新、图片查看、布局设计)

news2024/11/28 9:29:12

文章目录

    • 一、引言
    • 二、设计
      • 1、下拉刷新
        • (1)依赖
        • (2)使用
      • 2、图片需求
    • 三、结论

一、引言

  • 描述:设计一个简单说说功能模块
  • 需求:
    1、能够下拉刷新,更新数据
    2、一条说说里允许包含多张图片,图片能够放大查看
  • 难度:初级
  • 知识点:
    1、Swiperefreshlayout
    2、适配器Adapter
    3、对话框Dialog
    4、文字图标Icon

二、设计

1、下拉刷新

  • 思路

       使用官方提供的解决方案SwipeRefreshLayout,具有简单、灵活的特点。不足之处是无法刷新头部和加载更多的功能。

(1)依赖

    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03'

(2)使用

  • 效果图

在这里插入图片描述

  • UI界面
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipe"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

	<!-- 需要刷新的界面 -->

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout/>
  • 后台
	/**
     * @title:下拉刷新
     * @param activity
     */
    private void getSwipeRefreshLayout(final View activity) {
        final SwipeRefreshLayout swipeRefreshLayout = activity.findViewById(R.id.swipe);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            //设置刷新时长为1秒
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //更新数据
                                Log.i("Home","刷新数据");
                                // 数据更新方法
                                swipeRefreshLayout.setRefreshing(false);
                            }
                        });
                    }
                }).start();
            }
        });
    }

2、图片需求

  • 思路

多张图片:内容适配器嵌套图片适配器
图片放大:使用对话框,将获取的图片数据放入对话框内展示

  • 效果图

在这里插入图片描述

  • UI界面
    (内容适配器)
<?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:padding="@dimen/hPadding"
    android:background="@drawable/shape"
    android:orientation="vertical"
    android:layout_marginBottom="8dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/userImage"
            android:layout_width="@dimen/huImage"
            android:layout_height="@dimen/huImage"
            android:layout_margin="@dimen/huImageMargin"/>

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

            <TextView
                android:id="@+id/userName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="@dimen/huName"/>

            <TextView
                android:id="@+id/sayTime"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="@dimen/hTime"/>
        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/hTextHeight"
        android:orientation="vertical"
        android:layout_marginLeft="@dimen/huImageMargin">

        <TextView
            android:id="@+id/sayText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/hTimeTop"
            android:textSize="@dimen/hName"
            android:textColor="@color/comm_hText"/>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/sayImages"
            android:layout_width="match_parent"
            android:layout_height="@dimen/hImage"
            android:layout_marginTop="@dimen/hTimeTop" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageView
                    android:layout_marginTop="3dp"
                    android:layout_marginRight="6dp"
                    android:layout_width="@dimen/position"
                    android:layout_height="@dimen/position"
                    android:src="@drawable/position"/>

                <TextView
                    android:id="@+id/sayPosition"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/comm_hText"
                    android:layout_marginRight="@dimen/positionRight"/>

            </LinearLayout>
        </RelativeLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/hTimeTop"
        android:layout_marginLeft="@dimen/huImageMargin">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="评论区"
            android:textSize="13dp"/>
    </LinearLayout>

</LinearLayout>

(图片适配器)

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

    <ImageView
        android:id="@+id/item_image"
        android:layout_width="@dimen/hImage"
        android:layout_height="@dimen/hImage" />

</LinearLayout>
  • 后台
    (实体)
public class Say {

    Long id;

    int status;

    Long userId;

    String text;

    String images;

    String time;

    String newTime;

    String position;
    // 其他
    String name;

    String image;

    public Long getId() {
        return id;
    }

    public int getStatus() {
        return status;
    }

    public Long getUserId() {
        return userId;
    }

    public String getText() {
        return text;
    }

    public String getImages() {
        return images;
    }

    public String getTime() {
        return time;
    }

    public String getNewTime() {
        return newTime;
    }

    public String getPosition() {
        return position;
    }

    public String getName() {
        return name;
    }

    public String getImage() {
        return image;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setImages(String images) {
        this.images = images;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public void setNewTime(String newTime) {
        this.newTime = newTime;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setImage(String image) {
        this.image = image;
    }

    @Override
    public String toString() {
        return "Say{" +
                "id=" + id +
                ", status=" + status +
                ", userId=" + userId +
                ", text='" + text + '\'' +
                ", images='" + images + '\'' +
                ", time='" + time + '\'' +
                ", newTime='" + newTime + '\'' +
                ", position='" + position + '\'' +
                ", name='" + name + '\'' +
                ", image='" + image + '\'' +
                '}';
    }
}

(内容适配器)

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

    private List<Say> sayList;  // 定义容器
//    private int say_admin; // 读取类型
    BitmapDrawable bitmapDrawable;
    private Handler handler = null;

    public SayAdapter(List<Say> listSay) {
        this.sayList = listSay;
    }

    // 绑定控件
    static class ViewHolder extends RecyclerView.ViewHolder {
        View sayView;
        ImageView userImage;
        TextView userName,sayTime,sayText,sayPosition;
        RecyclerView recyclerView;

        public ViewHolder(View itemView) {
            super(itemView);
            sayView = itemView;
            userImage = itemView.findViewById(R.id.userImage);
            userName = itemView.findViewById(R.id.userName);
            sayTime = itemView.findViewById(R.id.sayTime);
            sayText = itemView.findViewById(R.id.sayText);
            sayPosition = itemView.findViewById(R.id.sayPosition);
            recyclerView = itemView.findViewById(R.id.sayImages);
        }
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
        //加载适配器布局
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.say,parent,false);
        //循环加载适配器布局,从而达到减少资源使用
        final SayAdapter.ViewHolder holder = new SayAdapter.ViewHolder(view);
        // 模块点击点击事件
        holder.sayView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(parent.getContext(),sayList.get(viewType).getText(),Toast.LENGTH_SHORT).show();
            }
        });
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull final SayAdapter.ViewHolder holder, int position) {
        final Say s = sayList.get(position);
        holder.userName.setText(s.getName());
        holder.sayTime.setText((CharSequence) s.getTime());
        holder.sayText.setText(s.getText());
        holder.sayPosition.setText(s.getPosition());
        // userImage
        //用户名头像
        showUserImage(holder,s.getImage());
        // sayImages
        // 说说多图片显示
        showSayImage(holder,s.getImages());
    }

    /**
     * Returns the total number of items in the data set held by the adapter.
     *
     * @return The total number of items in this adapter.
     */
    @Override
    public int getItemCount() {
        return sayList.size();
    }

    /**
     * @title:头像显示
     * @param holder
     * @param url
     */
    private void showUserImage(final SayAdapter.ViewHolder holder, final String url){
        handler = new Handler();
        final Runnable runnable = new Runnable() {
            @Override
            public void run() {
                holder.userImage.setImageDrawable(bitmapDrawable);
            }
        };
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    bitmapDrawable = okHttp.getBitmap(Api.userImage,url);
                    handler.post(runnable);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * @title:说说图片显示
     * @param holder
     * @param say_images
     */
    private void showSayImage(ViewHolder holder, String say_images) {
        // 解析符合图片资源
        String[] sayImages = say_images.split("\\|");
        List<String> sayI = new ArrayList<>();
        Collections.addAll(sayI,sayImages);
        //1.获取RecyclerView控件信息
        //2.RecyclerView控件的使用方法
        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
        //3.横向滑动
        holder.recyclerView.setLayoutManager(layoutManager);
        //4.数据载入适配器,数据填充
        ImageAdapter adapter = new ImageAdapter(sayI);
        holder.recyclerView.setAdapter(adapter);
    }

}

(图片适配器)

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

    //定义一个list容器
    private List<String> listString;
    BitmapDrawable bitmapDrawable;
    private Handler handler = null;

    //绑定android界面控件
    static class ViewHolder extends RecyclerView.ViewHolder {

        View ImageView;
        ImageView hImage;

        public ViewHolder(View itemView) {
            super(itemView);
            ImageView = itemView;
            hImage = itemView.findViewById(R.id.item_image);
        }
    }

    public ImageAdapter(List<String> list){
        listString = list;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        //加载适配器布局
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.image,viewGroup,false);
        //循环加载适配器布局,从而达到减少资源使用
        final ViewHolder holder = new ViewHolder(view);
        //图片放大
        ImageFD(holder);
        return holder;
    }

    /**     图片放大与关闭    **/
    private void ImageFD(final ViewHolder holder) {
        //再次点击进行关闭
        holder.hImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取对应的图片对象
                ImageView imgView = new ImageView(holder.hImage.getContext());
                imgView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                imgView.setImageDrawable(bitmapDrawable);
                //思路是:使用对话框,将获取的图片数据放入对话框内展示
                final Dialog dialog = new Dialog(holder.ImageView.getContext(),android.R.style.Theme_Black_NoTitleBar_Fullscreen);
                dialog.setContentView(imgView);
                dialog.show();
                //再次点击进行关闭
                imgView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.dismiss();
                    }
                });
            }
        });
    }

    @Override
    public void onBindViewHolder(final ViewHolder viewHolder, int i) {
        //将数据依次与适配器匹配
        final String s = listString.get(i);
        handler = new Handler();
        final Runnable runnable = new Runnable() {
            @Override
            public void run() {
                viewHolder.hImage.setImageDrawable(bitmapDrawable);
            }
        };
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    bitmapDrawable = okHttp.getBitmap(Api.sayImage,s);
                    handler.post(runnable);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    @Override
    public int getItemCount() {
        return listString.size();
    }
}

三、结论

       正常的说说模块,按道理应该还需要点赞、收藏、分享、屏蔽等一些功能,这里我就不一一设计了。思路其实很简单:
       点赞:使用Redis收集点赞用户信息,每隔三十分钟使用Spring Task归档一次或者晚上人流量少时定点统一归档。
 
       收藏:独立设计一张表,主字段:当前用户id、说说id,app本地再设计一张表用于缓存,剩下的就是IDUS。
 
       分享:定义一个特定的链接,比如:https://www.xpq.com/abcdef其中www.xpq.com为网址,abcdef为说说识别字段。如果还需要设置分享时间,比如:https://www.xpq.com/20230609/30/abcdef。20230609为开始时间,30表示一个月的过期时间。
 
       屏蔽:本地数据库获取到的说说信息里添加一个state字段,用于界面显示的一个“撞针”。

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

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

相关文章

第七章 Electron Vue3实现音乐播放器

一、介绍 &#x1f351; &#x1f351; &#x1f351; 一个音乐播放器应该具备播放、暂停、上一首、下一首、播放模式&#xff08;单曲循环、列表循环、顺序播放……&#xff09;。除了这些比如还可以扩展进度条的展示、拖拽、音量大小的调节&#xff0c;如果资源允许的话可以…

跨境电商开发的基本流程

在全球化的浪潮下&#xff0c;跨境电商已成为一个热门的商业模式。然而&#xff0c;很多人在跨境电商开发的过程中遇到了许多问题。本文将介绍跨境电商开发的流程&#xff0c;希望能够帮助大家更好地了解这个行业。 首先&#xff0c;跨境电商开发的第一步是寻找合适的产品。这…

DOC文件丢失怎么恢复?用这7种方法找回

在日常生活和工作中&#xff0c;我们经常会因为各种原因丢失重要的DOC文件&#xff0c;这给我们带来了不小的困扰。但是&#xff0c;不必担心&#xff0c;在本文中&#xff0c;我们将带大家了解一下DOC文件丢失怎么恢复。 关于DOC文件 DOC文件是指一种微软公司开发的文字处理软…

【短视频抖音多账号管理系统源码开发路径】

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 短视频矩阵系统开发涉及到多个领域的技术&#xff0c;包括视频编解码技术、大数据处理技术、音视频传输技术、电子商务及支付技术等。因此&#xff0c;短视频矩阵系统开发人员需要具备扎实的计算机基础知识、出色的编…

多边形三角化Earcut分析,以mapbox EarCut源码举例

多边形三角化&#xff0c;简单来说&#xff0c;就是给定一圈有序的多边形点生成三角面片&#xff0c;EarCut的原理描述网络上有很多&#xff08;如https://blog.csdn.net/qq_24459491/article/details/102976671&#xff09;&#xff0c;就不细说了。但是有的时候看是一回事&am…

Ae 效果详解:Mocha AE

Ae菜单&#xff1a;效果/Boris FX Mocha/Mocha AE Effects/Boris FX Mocha/Mocha AE Ae菜单&#xff1a;动画/Track in Boris FX Mocha Animation/Track in Boris FX Mocha Mocha Pro 是一款强大的平面跟踪软件。既可作为独立软件运行&#xff0c;也提供了 Ae 的插件版本&#…

1.4C++运算符重载作函数

C运算符重载函数作为类成员函数 作为类成员函数时&#xff0c;运算符重载函数使用类的成员变量作为操作数。 写个 demo&#xff1a; 运算符重载函数作为类成员函数时&#xff0c;需要注意&#xff1a;运算符重载函数必须是类的成员函数&#xff0c;不能是普通函数或者全局函…

MIT6.024学习笔记(二)——图论(1)

学习不是为了竞争和战胜他人&#xff0c;而是为了更好地了解自己和世界。 - 达赖喇嘛 文章目录 图的相关概念涂色问题基础涂色方法&#xff08;贪婪算法&#xff09;证明 二分图匹配问题应用&#xff1a;稳定婚烟问题算法性质及其证明 图的相关概念 图的定义&#xff1a;一组&…

We need you | 隐语开源共建计划第一期任务等你认领

作为隐私计算开源界的一颗新星&#xff0c;隐语一直致力于推动隐私计算行业的发展&#xff0c;同时也在不断发展和完善中。通过开放、透明和共享的方式&#xff0c;协同行业优秀人才协同合作&#xff0c;推动隐私计算领域蓬勃发展&#xff0c;这是隐语开源的意义。因此&#xf…

FPGA多路视频叠加融合 HLS算法实现 提供2套工程源码和技术支持

目录 1、前言2、视频叠加模块的功能和性能3、HLS视频叠加融合设计4、vivado工程1--单路同源视频的缩放叠加详细设计方案vivado工程详解SDK工程详解 5、vivado工程2--两路非同源视频的缩放叠加详细设计方案vivado工程详解SDK工程详解 6、上板调试验证7、福利&#xff1a;工程代码…

MySQL底层数据结构

1、引入 一个sql语句在mysql中究竟是如何运行的&#xff1f;又应该通过怎样的方式去查找我们要找的数据&#xff1f;这里就涉及到几种存储数据的算法&#xff1b; 可以做索引的数据结构有数组、链表、二叉搜索树和B树&#xff08;B-树、B树&#xff09;。 2、各种数据结构 …

flutter多版本切换

方式一&#xff1a;符号连接(软链接) 注&#xff1a;无需修改环境变量&#xff0c;也不用重启AndroidStudio mac具体flutter版本切换操作步骤&#xff1a; 1、项目clean然后切换自己需要的分支 2、删除文件夹flutter目录文件&#xff08;这里的flutter是原来的符号连接&…

若依集成分库分表(一)

1.本次需求为同库分表 1.1 引入pom依赖 <!-- sharding-jdbc分库分表 --> <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-core</artifactId><version>4.1.1</version> </dependenc…

Linux内核中内存管理相关配置项的详细解析2

接前一篇文章&#xff1a;Linux内核中内存管理相关配置项的详细解析1 3. Default compressor&#xff08;默认压缩器&#xff09; 此项展开后如下图所示&#xff1a; 此项的内核源码详细解释为&#xff1a; Selects the default compression algorithm for the compressed cac…

谷歌发布一个免费的生成式人工智能课程

在过去几周&#xff0c;我们看到的都是AI将如何改变生活&#xff0c;无论是ChatGPT的文本生成&#xff0c;还是SD&#xff0c;Midjourney 的图像生成&#xff0c;这些AI的特点就是都是生成式的AI。而几天前&#xff0c;谷歌推出了一个生成式人工智能学习课程&#xff0c;课程涵…

美团太细了:Springcloud 微服务优雅停机,如何实现?

说在前面 关于Spring Boot、Spring Cloud应用的优雅停机&#xff0c;平时经常会被问到&#xff0c;这也是实际应用过程中&#xff0c;必须要掌握的点。 在40岁老架构师 尼恩的读者社区(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如美团、拼多多、极兔、有赞、希音的…

深度学习应用篇-计算机视觉-语义分割综述[5]:FCN、SegNet、Deeplab等分割算法、常用二维三维半立体数据集汇总、前景展望等

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

【新版】系统架构设计师 - 软件可靠性分析与设计

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 软件可靠性分析与设计考点摘要可靠性相关基本概念软件可靠性分析可靠性指标串联系统&#xff08;可靠性&#xff09;并联系统&#xff08;可靠性&#xff09;混合系统&#xff08;可靠性&#xff…

(转载)从0开始学matlab—总结

1.编程实例 下面的例子将向大家介绍如何用 MATLAB 解决问题。 例1 温度转换程序 问题&#xff1a; 设计一个 MATLAB 程序&#xff0c;读取一个华氏温度的输入&#xff0c;输出开尔文温度。 答案&#xff1a; 华氏温度和开尔文温度的转换关系式可在物理学课本中找到。其关系式…

压力测试分为稳定性测试和破坏性测试

压力测试分为稳定性测试和破坏性测试 压力测试是一种对软件系统进行负载测试的常见手段&#xff0c;可以评估其在不同负载条件下的稳定性、性能和可靠性等指标。常见的压力测试分为两种类型&#xff1a;稳定性测试和破坏性测试。 1. 稳定性测试 稳定性测试也称为基准测试&#…