近期项目中有类似淘宝首页分类的样式,需要带进度条样式:
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>