转载请注明地址: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; } }