效果是:点击按钮使一个自定义布局里的的控件交叉
初始化一下数据:
自定义控件的代码:
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();必须写上,只有前一个布局无效后才能再次布局