android 开发程序员

自定义控件交叉布局(customViewGroupCrossLa

2017-05-29  本文已影响0人  靓亮

效果是:点击按钮使一个自定义布局里的的控件交叉

初始化一下数据:
自定义控件的代码:

package test.pgl.com.customviewgroupcrosslayout;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Administrator on 2017/5/28.
 */

public class MyViewGroup extends ViewGroup {
    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //遍历所有的子view
        int left=0;
        int top=0;
        for (int i = 0; i < getChildCount(); i++) {
            //根据索引获取到当前的子view
            View childView = getChildAt(i);
            if(i%2==0){
                left = 0;
            }else{
                left = getMeasuredWidth()-childView.getMeasuredWidth();
            }
            //给每一个子view 摆放到一个合适的位置
            childView.layout(left,top,left+childView.getMeasuredWidth(),top+childView.getMeasuredHeight());
            //修改top实现每一个子view从上到下的叠放效果
            top+=childView.getMeasuredHeight();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //主动测量所有的孩子
        measureChildren(0,0);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="test.pgl.com.customviewgroupcrosslayout.MainActivity">

    <Button
        android:onClick="Cross"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮" />
    <test.pgl.com.customviewgroupcrosslayout.MyViewGroup
        android:id="@+id/myViewGroup"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:background="#ff0000"/>
        <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:background="#00ff00"/>
        <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:background="#0000ff"/>
        <View
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:background="#000000"/>
    </test.pgl.com.customviewgroupcrosslayout.MyViewGroup>
</LinearLayout>

效果:

Paste_Image.png

现在来处理点击按钮后的逻辑:

package test.pgl.com.customviewgroupcrosslayout;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    private MyViewGroup myViewGroup;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myViewGroup = (MyViewGroup) findViewById(R.id.myViewGroup);
    }

    public void Cross(View view) {
        myViewGroup.setFlag(!myViewGroup.isFlag());
    }
}

自定义控件的代码:

package test.pgl.com.customviewgroupcrosslayout;

        import android.content.Context;
        import android.util.AttributeSet;
        import android.view.View;
        import android.view.ViewGroup;

/**
 * Created by Administrator on 2017/5/28.
 */

public class MyViewGroup extends ViewGroup {
    private boolean flag=false;

    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
        //重新布局 使原有的布局无效 重新执行layout阶段    request 请求 要求
        requestLayout();
    }
    public boolean isFlag(){
        return flag;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //遍历所有的子view
        int left=0;
        int top=0;
        for (int i = 0; i < getChildCount(); i++) {
            //根据索引获取到当前的子view
            View childView = getChildAt(i);
            if(flag){
                if(i%2==0){
                    left = 0;
                }else{
                    left = getMeasuredWidth()-childView.getMeasuredWidth();
                }
            }else{
                if(i%2==0){
                    left = getMeasuredWidth()-childView.getMeasuredWidth();
                }else{
                    left = 0;
                }
            }
            //给每一个子view 摆放到一个合适的位置
            childView.layout(left,top,left+childView.getMeasuredWidth(),top+childView.getMeasuredHeight());
            //修改top实现每一个子view从上到下的叠放效果
            top+=childView.getMeasuredHeight();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //主动测量所有的孩子
        measureChildren(0,0);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

点击按钮后的设计逻辑是:
让布局交叉:就两种情况所以用true和false来区分:
这种布局点击按钮交叉无非就重新布局一次
所以:
点击按钮之前的布局 isFlag为false

两种情况 两种布局 一一对应

Paste_Image.png

当按钮点击,布局要改变就得让flag改变
所以要setFlag

 public void setFlag(boolean flag) {
        this.flag = flag;
        //重新布局 使原有的布局无效 重新执行layout阶段    request 请求 要求
        requestLayout();
    }

注意: requestLayout();必须写上,只有前一个布局无效后才能再次布局

上一篇下一篇

猜你喜欢

热点阅读