仿百度壁纸客户端(三)——首页单向,双向事件冲突处理,壁纸列表的实现

简介: <div class="markdown_views"><h1 id="仿百度壁纸客户端三首页单向双向事件冲突处理壁纸列表的实现">仿百度壁纸客户端(三)——首页单向,双向事件冲突处理,壁纸列表的实现</h1><h2 id="百度壁纸系列">百度壁纸系列</h2><blockquote> <p><a href="http://blog.csdn.net/qq_

仿百度壁纸客户端(三)——首页单向,双向事件冲突处理,壁纸列表的实现

百度壁纸系列

仿百度壁纸客户端(一)——主框架搭建,自定义Tab + ViewPager + Fragment

仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图

仿百度壁纸客户端(三)——首页单向,双向事件冲突处理,壁纸列表的实现

仿百度壁纸客户端(四)——自定义上拉加载实现精选壁纸墙

仿百度壁纸客户端(五)——实现搜索动画GestureDetector手势识别,动态更新搜索关键字

仿百度壁纸客户端(六)——完结篇之Gallery画廊实现壁纸预览已经项目细节优化


上回把广告轮播图给实现了,今天就来把主页的大部分功能给实现了

一.ScrollView和ViewPager滑动事件冲突的解决办法

我们仔细想想,我们的主页架构,首先他是上下滑动的,所以这样要一个ScrollView,然后就是轮播图和其他内容了,这样的话,上下滑动有事件,轮播图也有事件,我们先看下xml的实现原理

home_fragment_xml

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

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <com.lgl.baiduwallpaper.view.VPScrollLayout
                android:id="@+id/vp_scroll"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/vp_scroll"
                android:text="其他内容"
                android:textSize="50dp" />

        </RelativeLayout>
    </ScrollView>


</RelativeLayout>

這裡很清晰的可以看出层级关系了,他事件冲突时必然的,解决办法也是很简单,就单以这个架构来讲的话,其实只要判断他是上下滑动还是左右滑动就好,如果是左右滑动,就不给ScrollView传递事件了,如果是上下滑动的话,让ScrollView自身来处理了,所以我们需要重写ScrollView

DisScrollView

package com.lgl.baiduwallpaper.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;

/**
 * 事件冲突解决
 * Created by lgl on 16/4/3.
 */
public class DisScrollView extends ScrollView {

    //手指按下的开始坐标
    private float startX, startY;
    //手指移动的移动坐标
    private float currentX, currentY;
    //手指抬起的最后坐标
    private float endX, endY;
    //手指按下后的移动距离
    private float distanceX,distanceY;

    /**
     * 构造方法
     *
     * @param context
     * @param attrs
     */
    public DisScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 事件分发
     *
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 事件拦截
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {
            //按下事件
            case MotionEvent.ACTION_DOWN:
                //获取坐标
                startX = ev.getX();
                startY = ev.getY();
                break;
            //移动事件
            case MotionEvent.ACTION_MOVE:
                //获取坐标
                currentX = ev.getX();
                currentY = ev.getY();
                distanceX += Math.abs(currentX - startX);
                distanceY += Math.abs(currentY - startY);
                startX = currentX;
                startY = currentY;
                //判断滑动方向
                if(distanceX >distanceY){  //左右滑动,
                    //不拦截事件
                    return  false;
                }
                break;
        }
        //上下移动自身处理
        return super.onInterceptTouchEvent(ev);
    }
}

OK,我们运行一下

这里写图片描述

关键是把逻辑处理好

二.GridView实现壁纸列表

1.ScrollView和GridView事件冲突

我们可以看看百度壁纸的效果,我们也来实现一下

这里写图片描述

我们要实现的就是下面的一个壁纸列表,这里我们就要考虑一下了,怎么去实现,实际上,不管是ScrollView还是GridView他们都是内存超出屏幕才回去执行滑动事件,这样的话,我们自定义一个GridView把高直接写好就可以了

DisGridView

package com.lgl.baiduwallpaper.view;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;

/**
 * 事件冲突
 * Created by lgl on 16/4/3.
 */
public class DisGridView extends GridView {

    /**
     * 事件冲突
     *
     * @param context
     * @param attrs
     */
    public DisGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * View的测量,获得页面的整体尺寸
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);

        super.onMeasure(widthMeasureSpec, height);
    }
}

然后我们就可以写布局了

home_fragment.xml

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

    <com.lgl.baiduwallpaper.view.DisScrollView
        android:id="@+id/disScroolView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <com.lgl.baiduwallpaper.view.VPScrollLayout
                android:id="@+id/vp_scroll"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <com.lgl.baiduwallpaper.view.DisGridView
                android:horizontalSpacing="10dp"
                android:verticalSpacing="10dp"
                android:numColumns="2"
                android:id="@+id/gridview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@+id/vp_scroll" />

        </RelativeLayout>
    </com.lgl.baiduwallpaper.view.DisScrollView>


</RelativeLayout>

现在触摸事件已经OK了

2.实现壁纸列表

这里我们没有借口,就使用本地的壁纸了,但是完全都是按照网络请求操作来的,这里使用的解析图片的开源看是SmartImageView

开源地址:https://github.com/loopj/android-smart-image-view

既然要使用GridView,那就必须要有一个实体类和一个item吧

HomeGrid

package com.lgl.baiduwallpaper.entity;

/**
 * GridView数据实体类
 * Created by lgl on 16/4/3.
 */
public class HomeGrid {

    /**
     * 当我们开发的时候,这里应该是个接口,那应该是String类型
     * 我们现在模拟的是本地的图片,所以是int
     */

    public HomeGrid(){
        super();
    }

    public HomeGrid(String type, int img) {
        this.type = type;
        this.img = img;
    }

    private int img;
    //描述
    private String type;

    public int getImg() {
        return img;
    }

    public void setImg(int img) {
        this.img = img;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "HomeGrid{" +
                "img=" + img +
                ", type='" + type + '\'' +
                '}';
    }

}

grid_item.xml

<?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="200dp"
    android:orientation="vertical">

    <com.loopj.android.image.SmartImageView
        android:id="@+id/mySmartImageView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/tv_nice"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:alpha="0.3"
        android:background="#000"
        android:gravity="left|center_vertical"
        android:paddingLeft="15dp"
        android:textColor="#fff"
        android:textSize="16sp" />

</RelativeLayout>

然后我们回到HomeFragment中,我们定义一个方法initGridData

    /**
     * 初始化GridView的数据
     */
    private void initGridData() {
        for (int i = 0; i < 10; i++) {
            HomeGrid grid = new HomeGrid();
            grid.setImg(R.drawable.nice);
            grid.setType("美女");
            gridData.add(grid);
        }
    }

现在可以定义一个adapter了


    /**
     * GridView的adapter
     */
    private class GridViewAdapter extends BaseAdapter {

        private Context context;
        private LayoutInflater inflater;

        /**
         * 构造方法
         *
         * @param context
         */
        public GridViewAdapter(Context context) {
            this.context = context;
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return gridData.size();
        }

        @Override
        public Object getItem(int position) {
            return gridData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            //第一次加载
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.grid_item, null);
                viewHolder = new ViewHolder();
                viewHolder.img = (SmartImageView) convertView.findViewById(R.id.mySmartImageView);
                viewHolder.tv = (TextView) convertView.findViewById(R.id.tv_nice);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

//            viewHolder.img.setImageResource(gridData.get(position).getImg());
            viewHolder.img.setBackgroundResource(gridData.get(position).getImg());
            viewHolder.tv.setText(gridData.get(position).getType());
            //动态设置高度
            convertView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,300));

            return convertView;
        }
    }

    private static class ViewHolder {
        private SmartImageView img;
        private TextView tv;

    }

写到这里,基本上就可以看到效果了

这里写图片描述

但是还是有一些细节需要处理的,比图scroolview一进来需要回滚到第一行

//设置每次进入现最前面
disScroolView.smoothScrollTo(0,0);

看代码应该就能看的很清晰了吧,我们来演示一下

这里写图片描述

有一点小粗糙,这就需要各位自己去完善了

三.意见反馈

我们滑动到最后会发现,有一个意见反馈,我们去实现它

这里写图片描述

在这里我们先不做跳转,先只是十点他的点击效果吧,也是相当点击简单,我们只要在DisGridView加上一个布局

 <RelativeLayout
                android:clickable="true"
                android:background="@drawable/bottom_select"
                android:layout_below="@+id/gridview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <LinearLayout
                    android:layout_centerInParent="true"
                    android:gravity="center"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:src="@drawable/image_more_icon_feedback"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" />

                    <TextView
                        android:layout_marginLeft="5dp"
                        android:text="意见反馈"
                        android:textSize="18sp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" />

                </LinearLayout>



            </RelativeLayout>

这里写图片描述

就可以了,这里我们还要实现它的点击效果

bottom_select.xml

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

    <item android:drawable="@drawable/image_more_subitems_bottom_selected" android:state_enabled="true" android:state_pressed="true"></item>
    <item android:drawable="@drawable/image_more_subitems_bottom_selected"  android:state_pressed="true"></item>
    <item android:state_pressed="false" android:drawable="@drawable/image_more_subitems_bottom"></item>
</selector>

让我们来运行一下吧

这里写图片描述

这里我把完整的HomeFragment贴上,就不上传源码了

HomeFragment

package com.lgl.baiduwallpaper.fragment;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.lgl.baiduwallpaper.R;
import com.lgl.baiduwallpaper.entity.HomeGrid;
import com.lgl.baiduwallpaper.view.DisGridView;
import com.lgl.baiduwallpaper.view.DisScrollView;
import com.lgl.baiduwallpaper.view.VPScrollLayout;
import com.loopj.android.image.SmartImageView;

import java.util.ArrayList;

/**
 * 主页
 * Created by lgl on 16/3/31.
 */
public class HomeFragment extends Fragment {

    private VPScrollLayout vpScroll;
    private ViewPager myViewPager;
    private ArrayList<View> bitmap = new ArrayList<View>();
    private DisGridView mGridView;
    private ArrayList<HomeGrid> gridData = new ArrayList<HomeGrid>();
    private DisScrollView disScroolView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.home_fragment, container, false);
        findView(view);
        return view;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        initVPData();
        initGridData();
        myViewPager.setAdapter(new MyAdapter());
        //设置几秒轮播
        vpScroll.setPagerFromTime(1000);
        //设置adapter
        mGridView.setAdapter(new GridViewAdapter(getActivity()));
        //设置每次进入现最前面
        disScroolView.smoothScrollTo(0,0);

    }

    /**
     * 初始化GridView的数据
     */
    private void initGridData() {
        for (int i = 0; i < 10; i++) {
            HomeGrid grid = new HomeGrid();
            grid.setImg(R.drawable.nice);
            grid.setType("美女");
            gridData.add(grid);
        }
    }

    /**
     * 初始化图片
     */
    private void initVPData() {
        LayoutInflater inflater1 = getActivity().getLayoutInflater();
        View view1 = inflater1.inflate(R.layout.vp_seroll_item, null);
        view1.findViewById(R.id.vpImg).setBackgroundResource(R.mipmap.img1);
        bitmap.add(view1);

        LayoutInflater inflater2 = getActivity().getLayoutInflater();
        View view2 = inflater2.inflate(R.layout.vp_seroll_item, null);
        view2.findViewById(R.id.vpImg).setBackgroundResource(R.mipmap.img2);
        bitmap.add(view2);

        LayoutInflater inflater3 = getActivity().getLayoutInflater();
        View view3 = inflater3.inflate(R.layout.vp_seroll_item, null);
        view3.findViewById(R.id.vpImg).setBackgroundResource(R.mipmap.img3);
        bitmap.add(view3);

        LayoutInflater inflater4 = getActivity().getLayoutInflater();
        View view4 = inflater4.inflate(R.layout.vp_seroll_item, null);
        view4.findViewById(R.id.vpImg).setBackgroundResource(R.mipmap.img4);
        bitmap.add(view4);
    }

    /**
     * 绑定
     *
     * @param view
     */
    private void findView(View view) {
        vpScroll = (VPScrollLayout) view.findViewById(R.id.vp_scroll);
        //直接拿到
        myViewPager = vpScroll.getViewPager();

        mGridView = (DisGridView) view.findViewById(R.id.gridview);
        disScroolView = (DisScrollView) view.findViewById(R.id.disScroolView);

    }

    /**
     * adapter
     */
    private class MyAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return bitmap.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {

            return view == object;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
//            super.destroyItem(container, position, object);
            //删除
            ((ViewPager) container).removeView(bitmap.get(position));
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ((ViewPager) container).addView(bitmap.get(position));

            return bitmap.get(position);
        }
    }

    /**
     * GridView的adapter
     */
    private class GridViewAdapter extends BaseAdapter {

        private Context context;
        private LayoutInflater inflater;

        /**
         * 构造方法
         *
         * @param context
         */
        public GridViewAdapter(Context context) {
            this.context = context;
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return gridData.size();
        }

        @Override
        public Object getItem(int position) {
            return gridData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            //第一次加载
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.grid_item, null);
                viewHolder = new ViewHolder();
                viewHolder.img = (SmartImageView) convertView.findViewById(R.id.mySmartImageView);
                viewHolder.tv = (TextView) convertView.findViewById(R.id.tv_nice);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

//            viewHolder.img.setImageResource(gridData.get(position).getImg());
            viewHolder.img.setBackgroundResource(gridData.get(position).getImg());
            viewHolder.tv.setText(gridData.get(position).getType());
            //动态设置高度
            convertView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,300));

            return convertView;
        }
    }

    private static class ViewHolder {
        private SmartImageView img;
        private TextView tv;

    }
}

好了,我们首页就已经做好了,是不是非常的简单尼?在我们的分析之后,其实这个软件也就那么回事哈

Demo下载地址:http://download.csdn.net/detail/qq_26787115/9480171

目录
相关文章
|
25天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
34818 137
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
8天前
|
人工智能 自然语言处理 监控
OpenClaw skills重构量化交易逻辑:部署+AI全自动炒股指南(2026终极版)
2026年,AI Agent领域最震撼的突破来自OpenClaw(原Clawdbot)——这个能自主规划、执行任务的智能体,用50美元启动资金创造了48小时滚雪球至2980美元的奇迹,收益率高达5860%。其核心逻辑堪称教科书级:每10分钟扫描Polymarket近千个预测市场,借助Claude API深度推理,交叉验证NOAA天气数据、体育伤病报告、加密货币链上情绪等多维度信息,捕捉8%以上的定价偏差,再通过凯利准则将单仓位严格控制在总资金6%以内,实现低风险高频套利。
3462 23
|
21天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
7643 22
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
20天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
5275 12
|
22天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
5991 23
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手