zoukankan      html  css  js  c++  java
  • 模仿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;
        }
    }

     源码下载

  • 相关阅读:
    深入研究Servlet线程安全性问题
    Sun公司java语言编码规范
    JAVA的内省机制(introspector)与反射机制(reflection)[转]
    Oracle的悲观锁和乐观锁
    java中120个经典问题
    自定义Java异常
    Java事务处理总结
    Tomcat内存溢出的三种情况及解决办法分析
    .net基础
    C#.Net中的转义
  • 原文地址:https://www.cnblogs.com/Lee1992/p/3647150.html
Copyright © 2011-2022 走看看