模仿QQ网购的二级分类页面

 

转载请注明地址:http://www.cnblogs.com/Lee1992/p/3647150.html

最近在公司实在闲得蛋疼,用扣扣网购的时候,发现他的二级分类展示效果不错,就随手模仿做出来一个。

没JB我说个图?

大概思路:

具体的我已经写成控件,这里重点说下调用的方法

package com.leeorz.expandablelayout;

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

import com.example.clickextendlistview.R;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

public class MainActivity6 extends Activity {

    
  //数据源
private String[] category = {"分类1","分类2","分类3","分类4","分类5","分类6","分类7" ,"分类8","分类9","分类10","分类11","分类12","分类13" ,"分类14","分类15","分类16","分类17","分类18","分类19"}; private ExpandableLayout expandableLayout; private List<View> views = new ArrayList<View>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main6); initView(); init(); }   //实例化控件
private void initView(){ expandableLayout = (ExpandableLayout) this.findViewById(R.id.expandableLayout); expandableLayout.initConfig(MainActivity6.this); expandableLayout.setOnClickItemListener(mClickItemListener);//点击一级分类View时候的回调
expandableLayout.setScrollDuration(
600);//设置滑动的时间
}
private void init(){ LayoutInflater mInflater = LayoutInflater.from(MainActivity6.this);       //创建一级分类的数据源(View)
for(int i = 0; i<category.length;i++){ View view = mInflater.inflate(R.layout.item, null); TextView tv = (TextView) view.findViewById(R.id.text); tv.setText(category[i]); tv.setTag(i); tv.setTextSize(30); views.add(view); } expandableLayout.setCategoryLayout(views);//将一级分类要显示的View设置进去    }   //点击一级分类时候的回调函数
public ExpandableLayout.OnClickItemListener mClickItemListener = new ExpandableLayout.OnClickItemListener() { @Override public void onClick(int index) { TextView tv = new TextView(MainActivity6.this); tv.setText("你点击了分类" + (index + 1)); tv.setTextSize(40); expandableLayout.setHideView(tv);//设置二级分类,在实际开发的时候,具体的UI操作先在外部做好,再设置进该控件即可。 } };
}

布局文件部分:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <Button android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="我是来占屏幕的"/>

    <com.leeorz.expandablelayout.ExpandableLayout
        android:id="@+id/expandableLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    </com.leeorz.expandablelayout.ExpandableLayout>

    <Button android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="我是来占屏幕的"/>
</LinearLayout>


核心部分:

ExpandableLayout.java

package com.leeorz.expandablelayout;

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

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;

import com.example.clickextendlistview.R;

@SuppressLint("NewApi")
public class ExpandableLayout extends LinearLayout implements OnClickListener{
    
    private Context mContext;
    private LayoutInflater mInflater;
    private View contentView;
    
    private String TASK = "ExpandableLayout_Task";

    private ScrollLayout mScrollLayout_top,mScrollLayout_bottom;
    private List<ItemView> layout = new ArrayList<ItemView>();
    
    private ScrollView sl_layout;
    
    private LinearLayout ll_hide_content;
    
    private OnClickItemListener mClickItemListener;
    private int windowHeight = 0;//屏幕的高度
//    private int scrollDuration = 500;
    
    private boolean topIsOpen = false;
    private boolean bottomIsOpen = false;
    
    private float scrollUpY = 0.0f;//向上滚动的高度
    private float scrollDownY = 0.0f;//向下滚动的高度
    
    private List<View> defaultViews = new ArrayList<View>();
    
    private ImageView iv_hide_image;
    
    public ExpandableLayout(Context context) {
        super(context);
        mContext = context;
        init();
        initView();
    }
    
    public ExpandableLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init();
        initView();
    }
    public ExpandableLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        init();
        initView();
    }

    private void init(){
        mInflater = LayoutInflater.from(mContext);
        contentView = mInflater.inflate(R.layout.layout_expandable, this, true);
        
        
    }
    
    public void initConfig(Activity activity){
        DisplayMetrics metric = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metric);
        windowHeight = metric.heightPixels;   // 屏幕高度(像素)
    }
    
    private void initView(){
        mScrollLayout_top = (ScrollLayout) contentView.findViewById(R.id.scrollView_top);
        mScrollLayout_top.setOnScrollListener(onTopScrollListener);
        
        mScrollLayout_bottom = (ScrollLayout) contentView.findViewById(R.id.scrollView_bottom);
        mScrollLayout_bottom.setOnScrollListener(onBottomScrollListener);
        
        sl_layout = (ScrollView) contentView.findViewById(R.id.sl_layout);
        
        
        ll_hide_content = (LinearLayout) contentView.findViewById(R.id.ll_hide_content);
    
        iv_hide_image = (ImageView) contentView.findViewById(R.id.iv_hide_image);
        iv_hide_image.setOnClickListener(this);
    }
    
    /**
     * 设置滑动时间
     */
    public void setScrollDuration(int duration){
//        scrollDuration = duration;
        mScrollLayout_bottom.setScrollDuration(duration);
        mScrollLayout_top.setScrollDuration(duration);
    }
    
    /**
     * 初始化ItemView
     */
    private void initItemView(){
        layout.clear();
        for(int i = 0;i<defaultViews.size();i++){

            ItemView item = new ItemView();
            item.setView(defaultViews.get(i));
            item.setState(ItemView.TOP);
            item.getView().setTag(i);
            item.getView().setOnClickListener(this);
            layout.add(item);
            mScrollLayout_top.addViewToEnd(layout.get(i).getView());//先全部加入top中
        }
    }
    
    /**
     * 添加分类layout
     */
    public void setCategoryLayout(List<View> list){
        defaultViews = list;
        initItemView();
    }
    
    private void setHideTitleBitmap(View view){
        
        iv_hide_image.setImageBitmap(ViewUtil.printScreen(view));
    }
    
    public void setOnClickItemListener(OnClickItemListener l){
        mClickItemListener = l;
    }
    
    /**
     * 设置隐藏页面的主要内容
     */
    public void setHideView(View view){
        ll_hide_content.removeAllViews();
        ll_hide_content.addView(view);
    }
    
    @Override
    public void onClick(View v) {
        //没有滑动完的话就返回
        if(mScrollLayout_bottom.isScroll & mScrollLayout_top.isScroll){
            return;
        }
        
        if(topIsOpen & bottomIsOpen){
            showCategoryView();
            close();    
        }else{
            if(v.getTag() == null){
                return;
            }
            int index = (Integer) v.getTag();
            open(index,v);
            setHideTitleBitmap(v);
            if(mClickItemListener != null){
                mClickItemListener.onClick(index);
            }
        }
    }
    
    /**
     * 关闭
     */
    private void close(){

        Log.d(TASK, "实际close的方法");
            scrollToBottom(mScrollLayout_top,scrollUpY * -1);
            scrollToTop(mScrollLayout_bottom,scrollDownY);
    }
    
    /**
     * 打开
     * @param index
     * @param v
     */
    private void open(int index,View v){
            transposition(index);
            
            getScrollY(v);
            
            Log.d(TASK, "实际open的方法");
            
            scrollToTop(mScrollLayout_top,scrollUpY);
            scrollToBottom(mScrollLayout_bottom,scrollDownY * -1);
    }
    
    /**
     * 换位
     */
    private void transposition(int index){

        if(layout.get(index).getState() == ItemView.TOP){//点击了上半部分的item
            for(int i = 0;i<layout.size();i++){
                if(i>index){
                    if(layout.get(i).getState() == ItemView.TOP){
                        layout.get(i).setState(ItemView.BOTTOM);
                    }    
                }
            }            
        }else if(layout.get(index).getState() == ItemView.BOTTOM){//点击了下半部分的item
            for(int i = 0;i<layout.size();i++){
                if(i<=index){
                    if(layout.get(i).getState() == ItemView.BOTTOM){
                        layout.get(i).setState(ItemView.TOP);
                    }
                }
            }
        }

        mScrollLayout_top.clearAllView();
        mScrollLayout_bottom.clearAllView();
        
        for(int i = 0;i<layout.size();i++){
            if(layout.get(i).getState() == ItemView.TOP){
                mScrollLayout_top.addViewToEnd(layout.get(i).getView());
            }else if(layout.get(i).getState() == ItemView.BOTTOM){

                mScrollLayout_bottom.addViewToEnd(layout.get(i).getView());
            }
        }
    }
    
    private ScrollLayout.OnScrollListener onBottomScrollListener = new ScrollLayout.OnScrollListener() {
        
        @Override
        public void onEnd() {
            if(mScrollLayout_bottom.isScroll){
                bottomIsOpen = !bottomIsOpen;
            }
            
        }
    };
    
    private ScrollLayout.OnScrollListener onTopScrollListener = new ScrollLayout.OnScrollListener() {
        
        @Override
        public void onEnd() {
            if(mScrollLayout_top.isScroll){
                if(!topIsOpen){
                    hideCategoryView();
                }
                topIsOpen = !topIsOpen;
            }
        }
    };
    
    private void hideCategoryView(){
        sl_layout.setVisibility(View.GONE);
    }
    
    private void showCategoryView(){
        sl_layout.setVisibility(View.VISIBLE);
    }
    
    /**
     * 分开
     */
    public void scrollToTop(ScrollLayout v,float y){
        v.setScrollY(0,y);
        v.startScroll();
    }
    
    /**
     * 关闭
     */
    public void scrollToBottom(ScrollLayout v,float y){
        v.setScrollY(0,y);
        v.startScroll();
        
    }
    

    /**
     * 获取view在屏幕中的Y轴值
     * @param view
     * @return
     */
    @SuppressLint("NewApi")
    private void getScrollY(View view){
        
        int index = (Integer) view.getTag();
        //总高度
        int scrollHeight = sl_layout.getScrollY();
        int viewHeight = index * view.getHeight();
        scrollUpY = viewHeight - scrollHeight;
        scrollDownY = windowHeight - scrollUpY;
        
    }
    
    /**
     * 设置点击事件的回调
     */
    public interface OnClickItemListener{
        public void onClick(int index);
    }
}

ScrollLayout.java

package com.leeorz.expandablelayout;

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

import com.example.clickextendlistview.R;

import android.annotation.SuppressLint;
import android.content.Context;
import android.provider.Settings.System;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Scroller;

public class ScrollLayout extends LinearLayout {

    private Scroller mScroller;
    private float fromY;
    private float toY;
    private Context mContext;
    private View contentView;
    private LinearLayout ll_root;
    private LayoutInflater mInflater;
    
    private OnScrollListener mOnScrollListener;
    
    public boolean isScroll = false;
    private List<View> views = new ArrayList<View>();
    
    private int scrollDuration = 600;//滑动时间
    
    public ScrollLayout(Context context) {
        super(context);
        mContext = context;
        init();
    }
    
    public ScrollLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init();
    }
    
    @SuppressLint("NewApi")
    public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        init();
    }

    private void init(){
        mScroller = new Scroller(mContext);
        mInflater = LayoutInflater.from(mContext);
        contentView = mInflater.inflate(R.layout.layout_scroll, this,true);
        ll_root = (LinearLayout) contentView.findViewById(R.id.ll_root);
    }
    
    public View getLastView(){
        return views.get(views.size() - 1);
    }
    
    public void addViewToFirst(View v){
        ll_root.addView(v, 0);
        views.add(0, v);
    }
    
    public void addViewToEnd(View v){
        ll_root.addView(v);
        views.add(v);
    }
    
    public void clearAllView(){
        for(View v : views){
            ll_root.removeView(v);
        }
        views.clear();
    }
    
    /**
     * 移除第一个子View
     */
    public void removeFirstView(){
        ll_root.removeView(views.get(0));
        views.remove(0);
    }

    /**
     * 移除最后一个子View
     */
    public void removeLastView(){
        ll_root.removeView(views.get(views.size() - 1));
        views.remove(views.size() - 1);
    }
    
    public int getItemCount(){
        return views.size();
    }
    
    public void setScrollDuration(int duration){
        this.scrollDuration = duration;
    }
    
    public void setScrollY(float fromY,float toY){
        this.fromY = fromY;
        this.toY = toY;        
        
    }
    
    public void setOnScrollListener(OnScrollListener l){
        this.mOnScrollListener = l;
    }
    
    private long starScrollTime = 0;
    @SuppressLint("NewApi")
    public void startScroll(){
//        Log.d("toY Value", ""+toY);
        mScroller.startScroll(mScroller.getCurrX(), mScroller.getCurrY(), 0, (int)toY,scrollDuration);
        isScroll = true;
        starScrollTime = java.lang.System.currentTimeMillis();
        invalidate();
    }
    
    @SuppressLint("NewApi")
    @Override
    public void computeScroll() {
        //先判断mScroller滚动是否完成  
        if (mScroller.computeScrollOffset()) {  
          
            //这里调用View的scrollTo()完成实际的滚动  
            contentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            //必须调用该方法,否则不一定能看到滚动效果  
            postInvalidate();  
        }else if(!mScroller.computeScrollOffset()){
            if(mOnScrollListener != null || isScroll){
                if(java.lang.System.currentTimeMillis() - starScrollTime >= scrollDuration){
                    mOnScrollListener.onEnd();
                    isScroll = false;                   
                }
            }
        }
        super.computeScroll();  
    }
    
    /**
     * 完成动画之后的回调接口
     */
    public interface OnScrollListener{
        public void onEnd();
    }
}

ViewUtil.java 用于控件截图

package com.leeorz.expandablelayout;

import java.io.ByteArrayOutputStream;

import android.graphics.Bitmap;
import android.view.View;

public class ViewUtil {

    /**
     * 对控件截图。
     * @param v 需要进行截图的控件。
     *            
     * @param quality 图片的质量
     *           
     * @return 该控件截图的byte数组对象。
     */
    public static byte[] printScreen(View v, int quality) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        v.setDrawingCacheEnabled(true);
        v.buildDrawingCache(true);
        Bitmap bitmap = v.getDrawingCache();
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
        return baos.toByteArray();
    }
    /**
     * 对控件截图。
     *
     * @param v 需要进行截图的控件
     *            
     * @return 该控件截图的Bitmap对象。
     */
    public static Bitmap printScreen(View v) {
        v.setDrawingCacheEnabled(true);
        v.buildDrawingCache();
        return v.getDrawingCache();
    }

}

ItemView.java

package com.leeorz.expandablelayout;

import android.view.View;

public class ItemView  {

    public final static int TOP = 1;
    public final static int BOTTOM = 2;
    
    private View view;
    private int state = TOP;
    
    public View getView() {
        return view;
    }
    public void setView(View view) {
        this.view = view;
    }
    public int getState() {
        return state;
    }
    public void setState(int state) {
        this.state = state;
    }
}

 源码下载

原文地址:https://www.cnblogs.com/Lee1992/p/3647150.html