實現電商應用分類主頁功能

1.需求背景:

需要實現類似淘寶,京東app分類主頁的功能,左側列表是一級標題,右側展示二級標題和三級詳細列表,右側展示列表在底部繼續上可以切換到下一個子分類信息,或者在頂部繼續下拉切換到上一個子分類信息。
效果圖如下:
在這裏插入圖片描述
三級數據數據模型如下:

{
    "id":4,
    "name":"美妝",
    "sname":"美妝",
    "level":0,
    "parent_id":0,
    "logo":null,
    "children":[
        {
            "id":62,
            "name":"彩妝",
            "sname":"彩妝",
            "level":1,
            "parent_id":4,
            "logo":"https://img.daff9.cn/biyingniao/images/other/1909/5d80d7d33d93a.jpg",
            "children":[
                {
                    "id":63,
                    "name":"彩妝套裝",
                    "sname":"彩妝套裝",
                    "level":2,
                    "parent_id":62,
                    "logo":"https://img.daff9.cn/biyingniao/images/other/1909/5d8b375dae870.jpg",
                    "children":[

                    ]
                }
            ]
        }
    ]
}
2.實現思路:

佈局文件中主要分三大塊,頂部搜索框區域較爲簡單,暫時略過,底部分類主內容展示區域通過左側一個recycleview將分類信息中的一級標題展示出來,右側則通過scrollview不斷添加二級分類和三級分類信息,scrollview中每一個子view都是頂部是二級分類標題,列表則是三級分類詳細信息(標題和圖片)。
scrollview子view實現如下:
category_right_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:descendantFocusability="blocksDescendants"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/right_item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:textSize="14sp"
        android:textColor="@color/category_main_title_unselect"
        android:fontFamily="NotoSansCJKsc-Regular"
        android:layout_marginTop="13dp"
        android:layout_marginStart="10dp"
        android:layout_marginBottom="11dp"
        />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/right_box"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/right_item_title"
        android:background="@drawable/cate_right_flex_bg"
        android:paddingBottom="14dp"
        />

</RelativeLayout>

CategoryFlowView.java

public class CategoryFlowView extends LinearLayout {

    private static final String TAG = "CategoryFlowView";
    private Context context;
    private RecyclerView boxLayout;
    private TextView title;
    private CategorySecondItemBean data;

    public CategoryFlowView(Context context) {
        this(context, null);
    }

    public CategoryFlowView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CategoryFlowView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

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

    private void init(Context cn) {
        context = cn;
        LayoutInflater inflater = LayoutInflater.from(cn);
        View rootView = inflater.inflate(R.layout.category_right_item, this);
        title = (TextView) rootView.findViewById(R.id.right_item_title);
        boxLayout = (RecyclerView) rootView.findViewById(R.id.right_box);
    }

    public void setData(CategorySecondItemBean bean) {
        this.data = bean;
        title.setText(bean.getName());
        List<CategoryThirdItemBean> children = bean.getChildren();
        if (children != null && children.size() != 0) {
            CategoryRecycleAdapter adapter = new CategoryRecycleAdapter(context, children);
            GridLayoutManager layoutManager = new GridLayoutManager(context, 3) {
                @Override
                public boolean canScrollVertically() {
                    return false;
                }
            };

            boxLayout.setLayoutManager(layoutManager);
            boxLayout.setAdapter(adapter);
        } else {
            this.setVisibility(View.GONE);
        }
    }

}

ScrollView實現滑動到頂部或者底部後繼續拉動產生回調事件,該功能通過重載onOverScrolled實現:
ScrollView.java中有代碼如下:

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        ......
        switch (actionMasked) {
            case MotionEvent.ACTION_DOWN: 
                ......
            case MotionEvent.ACTION_MOVE:
                ......
                如果是拖動的話
                if (mIsBeingDragged) {
                    
                    // Calling overScrollBy will call onOverScrolled, which
                    // calls onScrollChanged if applicable.
                    //調用overScrollBy將會調用onOverScrolled,它將會調用onScrollChanged如果適用的話
                    if (overScrollBy(0, deltaY, 0, mScrollY, 0, range, 0, mOverscrollDistance, true)
                            && !hasNestedScrollingParent()) {
                        ......
                    }

                    ...

自定義scrollview後重載onOverScrolled,測試中打印日誌發現果然能夠證明之前的猜想,到了頂部或者底部繼續上下拉會調用該接口,遂自定義scrollview如下:
CouponScrollView.java

public class CouponScrollView extends ScrollView {

    private OverScrollListener overScrollListener;

    private int count = 0;

    private boolean top,bottom,overScrolled;

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

    public void setOverScrollListener(OverScrollListener listener) {
        this.overScrollListener = listener;
    }

    public void init() {
        count = 0;
        top = false;
        bottom = false;
        overScrolled = false;
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        if(overScrollListener == null) {
            return;
        }
        if(clampedY) {
            count++;
        } else {
            count=0;
        }
        if(count == 6) {
            overScrolled = true;
            if(scrollY == 0) {
                //滑動到了頂部
                top = true;
                bottom = false;
            } else {
                //滑動到了底部
                top = false;
                bottom = true;
            }
        }

    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (overScrollListener != null && overScrolled) {
                    overScrolled = false;
                    overScrollListener.overScrolled(top,bottom);
                }
                break;
            default:
                break;
        }
        return super.onTouchEvent(ev);
    }

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    public interface OverScrollListener {
        void overScrolled(boolean top, boolean bottom);
    }
}

剩下的功能就是從網上或者本地文件中讀取分類信息,將分類信息分別填充到左側的一級標題recycleview中,和填充到CategoryFlowView然後添加到右側的scrollview中,
完整代碼如下:
https://github.com/tenghuihua/category

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章