Android Studio实现解析HTML获取json,解析json图片URL,将URL存到list,进行瀑布流展示

目录

        • 效果
        • build.gradle(app)添加的依赖(用不上的可以不加)
        • AndroidManifest.xml
        • 错误
        • activity_main.xml
        • item_image.xml
        • MainActivity
        • Image适配器
        • ImageModel 接收图片URL

效果

在这里插入图片描述

build.gradle(app)添加的依赖(用不上的可以不加)

dependencies {
    implementation 'com.squareup.picasso:picasso:2.71828'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.airbnb.android:lottie:3.0.3'
    implementation 'com.facebook.fresco:fresco:0.9.0+'
    implementation 'org.jsoup:jsoup:1.14.1'
    implementation 'com.squareup.okhttp3:okhttp:4.9.1'
    implementation 'com.github.bumptech.glide:glide:4.12.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
    implementation 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
    implementation 'androidx.sqlite:sqlite:2.2.0'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.code.gson:gson:2.8.9'
    implementation 'com.alibaba:fastjson:1.2.67'
    implementation("com.squareup.okhttp3:okhttp:4.10.0")
    }

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <application
  android:usesCleartextTraffic="true">

错误

如果出现错误:app:checkDebugDuplicateClasses
参考这篇博客尝试解决

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

item_image.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:orientation="vertical"
    android:padding="5dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        android:adjustViewBounds="true" />

</LinearLayout>

MainActivity

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import android.os.Bundle;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private ImageAdapter mImageAdapter;
    public String html = "https://2k317b5009.goho.co/images/List?type=breakfast";
    private List<ImageModel> mImageUrlsList = new ArrayList<>();

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

        //使用单线程的线程池来异步执行 callable 对象中的任务,并在任务执行完成后获取结果并显示图片和进行其他操作
        //使用 ExecutorService 来执行一个 Callable 对象,并获取它的返回结果
        //创建一个单线程的线程池,用于执行任务
        ExecutorService executor = Executors.newSingleThreadExecutor();

        //将 callable 对象提交给线程池进行执行,并返回一个 Future 对象,该对象可以用于获取任务的执行结果
        Future<List<ImageModel>> future = executor.submit(callable);

        try {
            //通过调用 future.get() 方法来阻塞主线程,直到任务执行完成并返回结果。在这里,我们将返回的结果赋值给 imageUrls 变量
            List<ImageModel> imageUrls = future.get();

            //将获取到的图片列表传递给 showImages 方法,以显示图片和后续操作
            showImages(imageUrls);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            executor.shutdown();
        }
    }

    private void showImages(List<ImageModel> imageUrls) {
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView = findViewById(R.id.recyclerView);

        //通过设置RecyclerView的布局管理器为StaggeredGridLayoutManager,并指定每行或每列的单元格数量和布局方向,就可以实现错乱瀑布流的效果
        //spanCount:指定每行或每列的单元格数量。在这个例子中,设置为2,表示每行有两个单元格。
        //orientation:指定布局的方向,VERTICAL表示垂直
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));

        //自定义的适配器类 将数据绑定到RecyclerView中的每个列表项上
        ImageAdapter adapter = new ImageAdapter(imageUrls, this);

        //调用RecyclerView的setAdapter()方法,将适配器与RecyclerView关联
        mRecyclerView.setAdapter(adapter);
    }

    /**
     * 使用 java.util.concurrent 包来执行并发任务,可以通过创建 ExecutorService 和 Future 对象来实现
     * 在 onCreate() 方法中,我们创建了一个单线程的 ExecutorService,然后通过 submit() 方法将 HtmlParserTask 提交给线程池进行执行。
     * 接着,我们使用 future.get() 来获取并发任务的结果,并调用 showImages() 方法来展示图片
     */
    Callable<List<ImageModel>> callable = new Callable<List<ImageModel>>() {
        @Override
        public List<ImageModel> call() throws Exception {
            List<ImageModel> imageModels = new ArrayList<>();
            // 解析 HTML 获取图片 URL 的逻辑
            Document document = Jsoup.connect(html).get();

            //使用 Jsoup 连接到给定的 HTML 页面,并使用 body().text() 方法获取页面的纯文本内容
            String jsonString = document.body().text();

            //转换成object
            JSONObject jsonObject = new JSONObject(jsonString);

            //从jsonObject里面找一个ImageList的对象
            JSONArray jsonArray = jsonObject.getJSONArray("ImageList");
            String imageUrl = null;
            //开始遍历
            for (int i = 0; i < jsonArray.length(); i++) {
                //遍历ImageList里面的每个对象
                JSONObject item = jsonArray.getJSONObject(i);

                // 检查是否存在 "src" 键
                if (item.has("src")) {
                    imageUrl = item.getString("src");
                    //Log.e(TAG,imageUrl);
                    imageModels.add(new ImageModel(imageUrl));
                }

            }

            return imageModels;
        }

    };
}

Image适配器

import static android.content.ContentValues.TAG;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.List;
import java.util.Random;

//适配器类
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
    private List<ImageModel> imageList;
    private Context context;

    //有参构造
    public ImageAdapter(List<ImageModel> imageList, Context context) {

        Log.e(TAG, "ImageAdapter thread id= "+ Thread.currentThread().getId() + " name="+Thread.currentThread().getName());

        this.imageList = imageList;
        this.context = context;
    }

    //onCreateViewHolder() 方法用于创建RecyclerView的每个列表项的视图
    @NonNull
    @Override
    public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_image, parent, false);
        return new ImageViewHolder(view);
    }


    //onBindViewHolder() 方法用于将数据绑定到ViewHolder中的视图
    @Override
    public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {
        ImageModel imageModel = imageList.get(position);//获取特定位置的图像模型(ImageModel)对象,并从中获取图像URL
        String imageUrl = imageModel.getImageUrl();

        //使用Picasso库加载图像URL并显示在ViewHolder的ImageView
        Picasso.get()
                .load(imageUrl)
                .fit()
                .centerCrop()
                .into(holder.imageView);

        // 设置图片的高度为随机高度,以实现错乱瀑布流效果
        ViewGroup.LayoutParams layoutParams = holder.imageView.getLayoutParams();
        layoutParams.height = getRandomHeight();//随机高度
        holder.imageView.setLayoutParams(layoutParams);
    }

    // 获取随机高度
    private int getRandomHeight() {
        Random random = new Random();
        return random.nextInt(400) + 300; // 设置图片高度范围为300-700之间的随机值
    }

    //返回图像列表的大小,即列表中包含的图像数量
    @Override
    public int getItemCount() {
        return imageList.size();
    }

    //设置适配器的图像列表
    public void setImageList(List<ImageModel> imageList) {
        this.imageList = imageList;
    }

    public class ImageViewHolder extends RecyclerView.ViewHolder {
        ImageView imageView;

        //持有每个列表项的视图组件,这里是一个ImageView
        public ImageViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imageView);
        }
    }
}

ImageModel 接收图片URL

//接收图片url
public class ImageModel {
    private String imageUrl;

    public ImageModel(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public String getImageUrl() {
        return imageUrl;
    }
}


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

win10 maven 安装环境变量设置不成功

maven 按照正常步骤设置环境变量 输入命令总是不能正常现实mvn的版本 解决方案: 1.删除掉设置的用户环境变量 2.将maven的完整目录写入系统变量path中 3.将该路径放到所有变量的最前面 4.点击确定,重新打开cmd 输入 mvn -v 正常了

Java——一个Java实体类,表示一个试题的模型

这段代码是一个Java实体类&#xff0c;表示一个试题的模型。 该实体类具有以下属性&#xff1a; id&#xff1a;题号&#xff0c;表示试题的编号。title&#xff1a;题目&#xff0c;表示试题的题目内容。optionA&#xff1a;选项A&#xff0c;表示试题的选项A。optionB&#…

如何通过tomcat下载映射下载文件

1.1找到tomcat服务器中server.xml文件 !--doBase是静态资源路径位置&#xff0c; path作用相当于设置的key, doBase作用相当于value --> <Context path"/download" docBase"E:\testBackData"></Context>1.2 找到tomcat服务器中web.xml文…

JAVA JNA 调用C接口的三种方式

文章目录 1. 准备一个共享库文件2. JNA姿势1—继承Library接口3. JNA姿势2—直接NativeLibrary.getInstance3. JNA姿势3—Native方法 1. 准备一个共享库文件 test.c #include <stdio.h> int test(char *input){printf("input:%s\n",input);return 0; }libtes…

Wlan安全——认证与加密方式(WPA/WPA2)

目录 终端认证技术 WEP认证 PSK认证 802.1x认证与MAC认证 Portal认证 数据加密技术 WEP加密 TKIP加密 CCMP加密 TKIP和CCMP生成密钥所需要的密钥信息 802.11安全标准 WEP共享密钥认证、加密工作原理 WEP共享密钥认证 WEP加解密过程 PSK认证以及生成动态密钥的工…

共创无线物联网数字化新模式|协创数据×企企通采购与供应链管理平台项目成功上线

近日&#xff0c;全球无线物联网领先者『协创数据技术股份有限公司』&#xff08;以下简称“协创数据”&#xff09;SRM采购与供应链项目全面上线&#xff0c;并于近日与企企通召开成功召开项目上线总结会。 基于双方资源和优势&#xff0c;共同打造了物联网特色的数字化采购供…

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序

目录 一、iota函数 1. 函数解析 ​① 迭代器类型(补充) ② 头文件 ③ 参数 2. 函数用途与实例 二、sort函数 1、 函数解读 2、实现倒序排列 2.1 greater 与 less 模板参数 2.2 lambda表达式 三、下标绑定排序&#xff08;zip&#xff09; --- 833.字符串中的查找与替换 一、…

27- v-model 原理 组件应用

v-model 原理 原理: V-model本质上是一个语法糖。例如应用在输入框上&#xff0c;就是 value属性 和 input事件 的合写 作用: 提供数据的双向绑定 (1) 数据变,视图跟着变 : value (2) 试图变,数据跟着变: input 注意: $event 用于在模板中, 获取事件的形参 <template>…

RabbitMQ---基本消息模型

1、 基本消息模型 官方介绍&#xff1a; RabbitMQ是一个消息代理&#xff1a;它接受和转发消息。 你可以把它想象成一个邮局&#xff1a;当你把邮件放在邮箱里时&#xff0c;你可以确定邮差先生最终会把邮件发送给你的收件人。 在这个比喻中&#xff0c;RabbitMQ是邮政信箱&a…

无涯教程-PHP - Session选项

从PHP7 起&#xff0c; session_start()()函数接受一系列选项&#xff0c;以覆盖在 php.ini 中设置的会话配置指令。这些选项支持 session.lazy_write &#xff0c;默认情况下此函数为on&#xff0c;如果会话数据已更改&#xff0c;则会导致PHP覆盖任何会话文件。 添加的另一个…

【在Windows下搭建Tomcat HTTP服务】

文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器&#xff0c;不仅名字很有趣&#xff0…

Java并发工具类

JDK并发包中常用并发工具类&#xff1a; CountDownLatch、CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段&#xff1b; Exchanger工具类则提供了在线程间交换数据的一种手段。 等待多线程完成的CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成…

爬虫异常处理:异常捕获与容错机制设计

作为一名专业的爬虫程序员&#xff0c;每天使用爬虫IP面对各种异常情况是我们每天都会遇到的事情。 在爬取数据的过程中&#xff0c;我们经常会遇到网络错误、页面结构变化、被反爬虫机制拦截等问题。在这篇文章中&#xff0c;我将和大家分享一些关于如何处理爬虫异常情况的经…

创建和分析二维桁架和梁结构研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Jsp 解决out.print()输出多出空行

一、原因 在 JSP 中&#xff0c;HTML 标签和 JSP 指令之外的内容会被当作文本处理&#xff0c;包括空行、空格和制表符等。当 JSP 引擎解析 JSP 页面时&#xff0c;会将这些文本内容原封不动地输出到响应中。 http响应 二、解决方法 在Jsp页面最前端添加 <% page trimDir…

【Linux】动态库和静态库

动态库和静态库 软链接硬链接硬链接要注意 自定义实现一个静态库(.a)解决、使用方法静态库的内部加载过程 自定义实现一个动态库&#xff08;.so&#xff09;动态库加载过程 静态库和动态库的特点 软链接 命令:ln -s 源文件名 目标文件名 软链接是独立连接文件的&#xff0c;他…

【Winform学习笔记(八)】通过委托实现跨窗体传值

通过委托实现跨窗体传值 前言正文1、委托及事件2、通过委托实现跨窗体传值的步骤1.在子窗体中定义委托2.在子窗体中声明一个委托类型的事件3.调用委托类型事件4.在实例化子窗体后&#xff0c;子窗体订阅事件接受方法5.实现具体的事件 3、具体示例4、完整代码5、实现效果 前言 …

论文阅读_条件控制_ControlNet

name_en: Adding Conditional Control to Text-to-Image Diffusion Models name_ch: 向文本到图像的扩散模型添加条件控制 paper_addr: http://arxiv.org/abs/2302.05543 date_read: 2023-08-17 date_publish: 2023-02-10 tags: [‘图形图像’,‘大模型’,‘多模态’] author: …

解决政务审计大数据传输难题!镭速传输为政务行业提供解决方案

政务行业是国家治理的重要组成部分&#xff0c;涉及到国家安全、社会稳定、民生福祉等方面。随着信息技术的快速发展和革新&#xff0c;政务信息化也迎来了新一轮的升级浪潮。国家相继出台了《国家信息化发展战略纲要》《“十三五”国家信息化规划》《“十四五”推进国家政务信…

华为OD机试 - 最佳植树距离 - 二分查找(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、备注说明五、二分查找六、解题思路七、Java算法源码八、效果展示1、输入2、输出3、说明 一、题目描述 按照环保公司要求&#xff0c;小明需要在沙化严重的地区进行植树防沙工作&#xff0c;初步目标是种植一条直线的树带。 由于…