横向ListView(一) ——开篇,基础逻辑实现

本文介绍了Android开发者自创横向ListView的过程,旨在记录开发思路并分享学习。文章适合已了解ListView原理的开发者阅读,内容包括实现基本逻辑、事件处理、布局优化等,后续将探讨更多功能实现。
摘要由CSDN通过智能技术生成

第一次写博文,写得不好的地方还望各位看客见谅

为了学习自定义软件开发,且定制出满足自己需求的控件(不需要将就地使用第三方源码),本人花了一周的时间开发了个横向ListView,写博客是为了记录整个开发过程及思路,也能和各位看客一起学习和探讨。

这一系列文章是针对的读者是已经了解listview缓存和工作原理的android开发人员,如果对listview缓存和工作原理还不了解的读者,可以查看以下文章:

《Android研究院之ListView原理学习与优化总结》

 

目前横向ListView的可替代方案有以下三种:

1.HorizontalScrollView——android官方提供

2.RecyclerView——android6.0提供的

3.第三方开源控件

尽管有众多的选择,但感觉还是自己会实现比较酷一些,还有就是,自己的东西可以随便改改改改改。

 

本篇文章将介绍横向ListView的实现基本思路,在接下来的一系列文章中将不断介绍整个控件的完善思路(包括:实现快速滚动、添加头/尾视图、添加滚动条、实现下拉刷新/上拉加载等)。

参考文章: 《Android UI开发: 横向ListView(HorizontalListView)及一个简单相册的完整实现》

 


 横向ListView的基础逻辑:

 1.新建java类,类名:HorizontalListView
 2.继承AdapterView
 3.实现setAdapter()和getAdapter()方法(需要为adapter注册数据观察器)
 4.实现onTouchEvent()方法响应事件(采用android提供的手势解析器GestureDetector解析事件)
 5.实现onLayout方法,布局列表项
     1).计算当前列表发生滚动的滚动“位移值”,记录已经发生有效滚动的“位移累加值”
     2).根据“位移值”提取需要缓存的视图(已经滚动到可视区域外的列表项)
     3).根据“位移值”设置需要显示的的列表项
     4).根据整体列表“显示偏移值”整顿所有列表项位置(调用子view的列表项)
     5).计算可以发生滚动的“最大位移值”

 

先上代码:

package com.hss.os.horizontallistview.history_version;

import android.content.Context;
import android.database.DataSetObserver;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 横向ListView的基础逻辑
 * 1.继承AdapterView
 * 2.实现setAdapter()和getAdapter()方法(需要为adapter注册数据观察器)
 * 3.实现onTouchEvent()方法响应事件(采用android提供的手势解析器GestureDetector解析事件)
 * 4.实现onLayout方法,布局列表项
     1).计算当前列表发生滚动的滚动“位移值”,记录已经发生有效滚动的“位移累加值”
     2).根据“位移值”提取需要缓存的视图(已经滚动到可视区域外的列表项)
     3).根据“位移值”设置需要显示的的列表项
     4).根据整体列表“显示偏移值”整顿所有列表项位置(调用子view的列表项)
     5).计算可以发生滚动的“最大位移值”
 *
 * Created by hss on 2017/7/17.
 */

public class HorizontalListView1 extends AdapterView<ListAdapter> {


    private ListAdapter adapter = null;
    private GestureDetector mGesture;
    private Queue<View> cacheView = new LinkedList<>();//列表项缓存视图
    private int firstItemIndex = 0;//显示的第一个子项的下标
    private int lastItemIndex = -1;//显示的最后的一个子项的下标
    private int scrollValue=0;//列表已经发生有效滚动的位移值
    private int hasToScrollValue=0;//接下来列表发生滚动所要达到的位移值
    private int maxScrollValue=Integer.MAX_VALUE;//列表发生滚动所能达到的最大位移值(这个由最后显示的列表项决定)
    private int displayOffset=0;//列表显示的偏移值(用于矫正列表显示的所有子项的显示位置)

    public HorizontalListView1(Context context) {
        super(context);
        init(context);
    }

    public HorizontalListView1(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public HorizontalListView1(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public HorizontalListView1(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }


    private void init(Context context){
        mGesture = new GestureDetector(getContext(), mOnGesture);
    }

    private void initParams(){
        removeAllViewsInLayout();
        if(adapter!=null&&lastItemIndex<adapter.getCount())
            hasToScrollValue=scrollValue;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值