效果图:
自定义View
MyLinearLayout.java
public class MyLinearLayout extends ViewGroup { private int marginTop = 50; private int marginLeft = 50; private int initTop = 50; private int initLeft = 50; //0 纵向 1 横向 private int oritation; public MyLinearLayout(Context context) { this(context, null); MyLinearLayout myLinearLayout = new MyLinearLayout(context); myLinearLayout.hashCode(); } public MyLinearLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context,attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int totalHeight = 0; int totalWidth = 0; measureChildren(widthMeasureSpec, heightMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); if (oritation == 0) { //判断高 switch (modeHeight) { //dp match_parent case MeasureSpec.EXACTLY: totalHeight = sizeHeight; totalWidth = sizeWidth; break; //wrap_content case MeasureSpec.AT_MOST: for (int i = 0; i < getChildCount(); i++) { View childAt = getChildAt(i); totalHeight += childAt.getMeasuredHeight() + marginTop; //Log.e("myMessage", "AT_MOST" + totalHeight); } totalHeight += initTop; totalWidth = getChildAt(0).getMeasuredWidth() + marginLeft * 2; break; case MeasureSpec.UNSPECIFIED: break; } } else if (oritation == 1) { //判断高 switch (modeWidth) { //dp match_parent case MeasureSpec.EXACTLY: totalWidth = sizeWidth; totalHeight = sizeHeight; break; //wrap_content case MeasureSpec.AT_MOST: for (int i = 0; i < getChildCount(); i++) { View childAt = getChildAt(i); totalWidth += childAt.getMeasuredWidth() + marginLeft; } totalWidth += initLeft; totalHeight = getChildAt(0).getMeasuredHeight() + marginTop * 2; break; case MeasureSpec.UNSPECIFIED: break; } }else if (oritation == 2) { switch (modeHeight) { //dp match_parent case MeasureSpec.EXACTLY: totalHeight = sizeHeight; totalWidth = sizeWidth; break; //wrap_content case MeasureSpec.AT_MOST: for (int i = 0; i < getChildCount(); i++) { View childAt = getChildAt(i); totalHeight += childAt.getMeasuredHeight() + marginTop; //Log.e("myMessage", "AT_MOST" + totalHeight); } totalHeight += initTop; //totalWidth = getChildAt(0).getMeasuredWidth() + marginLeft * 2; break; case MeasureSpec.UNSPECIFIED: break; } switch (modeWidth) { //dp match_parent case MeasureSpec.EXACTLY: totalWidth = sizeWidth; totalHeight = sizeHeight; break; //wrap_content case MeasureSpec.AT_MOST: for (int i = 0; i < getChildCount(); i++) { View childAt = getChildAt(i); totalWidth += childAt.getMeasuredWidth() + marginLeft; } totalWidth += initLeft; //otalHeight = getChildAt(0).getMeasuredHeight() + marginTop * 2; break; case MeasureSpec.UNSPECIFIED: break; } } setMeasuredDimension(totalWidth, totalHeight); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int mTop = initTop; int mLeft = 50; int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View childAt = getChildAt(i); childAt.layout(mLeft, mTop, childAt.getMeasuredWidth() + mLeft, childAt.getMeasuredHeight() + mTop); if (oritation == 0) { mTop += childAt.getMeasuredHeight() + marginTop; } else if (oritation == 1) { mLeft += childAt.getMeasuredWidth() + marginLeft; } else if (oritation ==2 ) { mTop += childAt.getMeasuredHeight() + marginTop; mLeft += childAt.getMeasuredWidth() + marginLeft; } } } private void init(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyLinearLayout); oritation = typedArray.getInteger(0, 0); } }attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyLinearLayout"> <attr name="oritation" format="enum"> <enum value="0" name="vertical"/> <enum value="1" name="horizontal"/> <enum value="2" name="all"/> </attr> <attr name="oritation2" format="integer"/> </declare-styleable> </resources>activity_main.xml
扫描二维码关注公众号,回复:
2784469 查看本文章
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:cj="http://schemas.android.com/apk/res-auto" tools:context="com.bwie.com.myapplication.MainActivity"> <com.bwie.com.myapplication.MyLinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" cj:oritation="horizontal" android:background="#6effff99"> <TextView android:layout_width="100dp" android:layout_height="50dp" android:gravity="center" android:background="@color/colorAccent" android:text="礼物走一圈"/> <TextView android:layout_width="100dp" android:layout_height="50dp" android:background="#90ff33" android:gravity="center" android:text="礼物走两圈"/> <TextView android:layout_width="100dp" android:layout_height="50dp" android:background="#f00342" android:gravity="center" android:text="礼物走三圈"/> <!--<TextView--> <!--android:layout_width="100dp"--> <!--android:layout_height="50dp"--> <!--android:background="#27f003"--> <!--android:gravity="center"--> <!--android:text="@string/text_content"/>--> </com.bwie.com.myapplication.MyLinearLayout> </LinearLayout>
自定义ScrollView
public class MyScrollView extends ScrollView { private OnScrollListener listener; public void setOnScrollListener(OnScrollListener listener) { this.listener = listener; } public MyScrollView(Context context) { super(context); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public interface OnScrollListener{ void onScroll(int scrollY); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if(listener != null){ listener.onScroll(t); } } }
自定义禁止左右滑动的ViewPager
public class NoScrollViewPager extends ViewPager { private boolean isScroll; public NoScrollViewPager(Context context, AttributeSet attrs){ super(context, attrs); } public NoScrollViewPager(Context context) { super(context); } /** * 1.dispatchTouchEvent一般情况不做处理 *,如果修改了默认的返回值,子孩子都无法收到事件 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { return super.dispatchTouchEvent(ev); // return true;不行 } /** * 是否拦截 * 拦截:会走到自己的onTouchEvent方法里面来 * 不拦截:事件传递给子孩子 */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // return false;//可行,不拦截事件, // return true;//不行,孩子无法处理事件 //return super.onInterceptTouchEvent(ev);//不行,会有细微移动 if (isScroll){ return super.onInterceptTouchEvent(ev); }else{ return false; } } /** * 是否消费事件 * 消费:事件就结束 * 不消费:往父控件传 */ @Override public boolean onTouchEvent(MotionEvent ev) { //return false;// 可行,不消费,传给父控件 //return true;// 可行,消费,拦截事件 //super.onTouchEvent(ev); //不行, //虽然onInterceptTouchEvent中拦截了, //但是如果viewpage里面子控件不是viewgroup,还是会调用这个方法. if (isScroll){ return super.onTouchEvent(ev); }else { return true;// 可行,消费,拦截事件 } } public void setScroll(boolean scroll) { isScroll = scroll; } }
自定义的二级列表(ExpandableListView)
public class MyExListView extends ExpandableListView { public MyExListView(Context context) { this(context, null); } public MyExListView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyExListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
自定义ListView(GridView)
public class MyListView extends GridView{ public MyListView(Context context) { super(context); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); } public MyListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int measureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, measureSpec); } }