仿淘宝首页分类,带seekbar进度条手势样式

近期项目中有类似淘宝首页分类的样式,需要带进度条样式:

1.页面布局

<?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="wrap_content"
    android:background="@android:color/white"
    android:orientation="vertical">

    <com.learn.taobaocateogory.MyHorizontalScrollView
        android:id="@+id/horizontal_scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none">

        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <com.learn.taobaocateogory.MyGridView
                android:id="@+id/top_category_gridview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:layout_marginLeft="2dp"
                android:layout_marginRight="2dp"
                android:background="#ffffff"
                android:columnWidth="55dp"
                android:gravity="center"
                android:numColumns="4"
                android:stretchMode="columnWidth" />
        </LinearLayout>
    </com.learn.taobaocateogory.MyHorizontalScrollView>

    <SeekBar
        android:id="@+id/mSeekBar"
        android:layout_width="45dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="14dp"
        android:background="@drawable/home_shape_dddddd_sort_indicator_gray_bg"
        android:focusable="true"
        android:maxHeight="4.0dip"
        android:minHeight="4.0dip"
        android:progress="0"
        android:progressDrawable="@drawable/home_shape_fast_scroll_bar_track"
        android:stateListAnimator="@null"
        android:thumb="@drawable/home_shape_fast_scroll_bar_thumb"
        android:visibility="visible"
        android:thumbOffset="0dp"
        android:paddingStart="0dp"
        android:paddingEnd="0dp"
        tools:ignore="UnusedAttribute" />

</LinearLayout>

2.用到的MyHorizontalScrollView

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;

/**
 * ClassName MyHorizontalScrollView
 * Create by rhf
 * Create on 2020/7/14 10:31
 * Description 自定义水平滚动的ScrollView
 */
public class MyHorizontalScrollView extends HorizontalScrollView {
    private float startX;
    private int currentScroll;
    private boolean firstOldL;
    private ScrollViewListener mListener;
    private int oldL;

    public MyHorizontalScrollView(Context context,
                                  AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

    public MyHorizontalScrollView(Context context) {
        super(context);
    }


    public interface ScrollViewListener {

        void onScrollChanged(int l, int t, int oldl, int oldt);

        void onScrollStopped(int scrollDistance);

    }

    private Handler mHandler;


    /**
     * 滚动监听间隔
     */
    private int scrollDealy = 1;

    public void setListener(ScrollViewListener listener) {
        mListener = listener;
    }

    public void setHandler(Handler handler) {
        this.mHandler = handler;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        Log.i("dan.y", "isfirstoldl:" + firstOldL);
        if (!firstOldL) {
            Log.i("dan.y", "isfirstoldl:" + firstOldL);
            oldL = oldl;
            firstOldL = true;
        }
        if (mListener != null) {
            mListener.onScrollChanged(l, t, oldl, oldt);

        }
        super.onScrollChanged(l, t, oldl, oldt);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = ev.getX();
                firstOldL = false;
                Log.i("dan.y", "startX:" + startX);
                break;
            case MotionEvent.ACTION_UP:
                float endX = ev.getX();
                currentScroll = this.getScrollX();
                if (mHandler != null) {
                    mHandler.postDelayed(scrollTask, scrollDealy);
                }
                break;

            default:
                break;
        }
        return super.onTouchEvent(ev);
    }

    Runnable scrollTask = new Runnable() {

        @Override
        public void run() {
            int newScroll = MyHorizontalScrollView.this.getScrollX();
            if (currentScroll == newScroll) {
                Log.i("dan.y", "oldl:" + oldL);
                firstOldL = false;
                mListener.onScrollStopped(currentScroll - oldL);
                mHandler.removeCallbacks(scrollTask);
            } else {
                currentScroll = MyHorizontalScrollView.this.getScrollX();
                postDelayed(scrollTask, scrollDealy);
            }
        }
    };

}

3.用的MyGridView

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

/**
 * ClassName MyGridView
 * Create by rhf
 * Create on 2020/7/14 10:32
 * Description 自定义GridView,兼容ScrollView
 */
public class MyGridView extends GridView {

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

    public MyGridView(Context context) {
        super(context);
    }

    public MyGridView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

4.用到的seekbar背景 home_shape_dddddd_sort_indicator_gray_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#dddddd" />
    <corners android:radius="2dp" />
    <stroke android:color="#dddddd" />

    <padding
        android:bottom="0dp"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp" />

</shape>

5.用到的home_shape_fast_scroll_bar_track.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="2dp" />
    <solid android:color="#E3E3E3" />

    <size
        android:width="45dp"
        android:height="4dp" />
</shape>

6.用到的home_shape_fast_scroll_bar_thumb.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="2dp" />
    <solid android:color="#FF6059" />
    <size
        android:width="30dp"
        android:height="4dp" />

</shape>

7.在Activity中的使用

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.SeekBar;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private MyHorizontalScrollView horizontalScrollview;
    private MyGridView topaCtegoryGridview;
    private SeekBar mSeekBar;
    private List<String> mTopSortData;
    private int defaultColumns = 4;
    private Handler handler;

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

        initView();
        initData();
        registerListener();
    }

    /**
     * 初始化View
     */
    private void initView() {
        horizontalScrollview = findViewById(R.id.horizontal_scrollview);
        horizontalScrollview.setHorizontalScrollBarEnabled(false);// 隐藏滚动条
        horizontalScrollview.setFocusable(false);

        topaCtegoryGridview = findViewById(R.id.top_category_gridview);
        mSeekBar = findViewById(R.id.mSeekBar);
    }


    /**
     * 水平滚动scrollview监听设置
     */
    private void registerListener() {
        handler = new Handler();
        horizontalScrollview.setHandler(handler);
        horizontalScrollview.setListener(new MyHorizontalScrollView.ScrollViewListener() {

            @Override
            public void onScrollChanged(int l, int t, int oldl, int oldt) {

                int mColumns = calculateNumClumns();
                if (mColumns > defaultColumns) {
                    mSeekBar.setProgress(oldl);//滑动的距离
                }
            }

            @Override
            public void onScrollStopped(int scrollDistance) {
            }
        });
    }

    /**
     * 初始化数据
     */
    private void initData() {

        mTopSortData = new ArrayList<>();
        mTopSortData.add("天猫新品");
        mTopSortData.add("今日爆款");
        mTopSortData.add("天猫国际");
        mTopSortData.add("饿了么");
        mTopSortData.add("天猫超市");
        mTopSortData.add("淘宝吃货");
        mTopSortData.add("闲鱼");
        mTopSortData.add("会员中心");
        mTopSortData.add("淘票票");
        mTopSortData.add("土货鲜食");
        mTopSortData.add("充值中心");
        mTopSortData.add("机票酒店");
        mTopSortData.add("领取淘币");
        if (mTopSortData.size() > 8) {
            mSeekBar.setVisibility(View.VISIBLE);
        } else {
            mSeekBar.setVisibility(View.INVISIBLE);
        }
        HomeTopSortAdapter topSortAdapter = new HomeTopSortAdapter(this, mTopSortData);
        topaCtegoryGridview.setAdapter(topSortAdapter);

        setValue();
    }

    /**
     * 设置gridview
     */
    private void setValue() {

        int numColumns = calculateNumClumns();
        int itemWidth = (AppUiUtils.getScreenWidth(this)) / defaultColumns;
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(numColumns * itemWidth,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        topaCtegoryGridview.setLayoutParams(params);

        topaCtegoryGridview.setColumnWidth(itemWidth);//设置条目宽度
        topaCtegoryGridview.setStretchMode(GridView.NO_STRETCH);
        topaCtegoryGridview.setNumColumns(numColumns);
        topaCtegoryGridview.setSelector(new ColorDrawable(Color.TRANSPARENT));
        int canMoveDistance = (numColumns - defaultColumns) * itemWidth;
        mSeekBar.setMax(canMoveDistance);

    }

    /**
     * 计算一屏幕显示多少列
     *
     * @return 一屏幕显示的列数
     */
    private int calculateNumClumns() {

        int totalCount = mTopSortData.size();
        int numberColumns;
        if (totalCount >= 8) {
            //当count大于8时  如下排列
            //| 1 | 3 | 5 | 7 |
            //| 2 | 4 | 6 | 8 |
            numberColumns = (totalCount % 2 == 0) ? totalCount / 2 : totalCount / 2 + 1;
        } else {
            //当count小于于8时  如下排列
            //| 1 | 2 | 3 | 4 |
            //| 5 | 6 | 7 | 8 |
            int defaultRows = 2;
            numberColumns = (totalCount % defaultRows == 0) ? totalCount / defaultRows : totalCount / defaultRows + 1;
            if (numberColumns < defaultColumns) {
                numberColumns = defaultColumns;
            }
        }
        return numberColumns;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
        }
    }
}

8.用到的HomeTopSortAdapter

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * ClassName HomeTopSortAdapter
 * Create by rhf
 * Create on 2020/7/14 10:49
 * Description 分类数据适配器
 */
public class HomeTopSortAdapter extends BaseAdapter {

    private Context mContext;
    private List<String> mData;

    public HomeTopSortAdapter(Context mContext, List<String> mData) {
        this.mContext = mContext;
        this.mData = mData;
    }

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

    @Override
    public Object getItem(int i) {
        return null;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {

        MyViewHolder holder;
        if (convertView == null) {
            holder = new MyViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.home_item_top_category, null);
            holder.tvCategoryName = convertView.findViewById(R.id.tv_category_name);
            holder.ivSortmage = convertView.findViewById(R.id.iv_sort_image);
            convertView.setTag(holder);
        } else {
            holder = (MyViewHolder) convertView.getTag();
        }

        holder.tvCategoryName.setText(mData.get(position));
        return convertView;
    }

    private class MyViewHolder {
        TextView tvCategoryName;
        ImageView ivSortmage;
    }

}

9.用到的条目布局home_item_top_category.xml

<?xml version="1.0" encoding="utf-8"?><!--
  ~ Copyright (C), 2016-2019, Shall Buy Life info. Co., Ltd.
  -->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rl_item"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <View
        android:id="@+id/view_top_line"
        android:layout_width="5dp"
        android:layout_height="22dp"
        android:background="@android:color/transparent" />

    <ImageView
        android:id="@+id/iv_sort_image"
        android:layout_width="46dp"
        android:layout_height="46dp"
        android:layout_below="@+id/view_top_line"
        android:layout_centerHorizontal="true"
        android:scaleType="fitXY"
        android:src="@drawable/common_shape_test_circle" />

    <TextView
        android:id="@+id/tv_category_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/iv_sort_image"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="6dp"
        tools:text="充值中心"
        android:textColor="#333333"
        android:textSize="14sp" />

</RelativeLayout>

10.用到的默认图片common_shape_test_circle.xml

<?xml version="1.0" encoding="utf-8"?>

<!--
  ~ Copyright (C), 2016-2019, Shall Buy Life info. Co., Ltd.
  -->

<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    android:useLevel="false">
    <solid android:color="#FFF2C3C6" />
    <size
        android:width="40dp"
        android:height="40dp" />

</shape>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值