自定义view流布局

布局

activity_main

<?xml version="1.0" encoding="utf-8"?>

<com.example.jingze12.TitleBarView
    android:id="@+id/title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

<com.example.jingze12.WeekGroupNameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:textColor="#00ff00"
    android:text="搜索历史"/>

<com.example.jingze12.WeekFlowLayout
    android:id="@+id/fl_search"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    />



<com.example.jingze12.WeekGroupNameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:text="热门搜索"/>

<com.example.jingze12.WeekFlowLayout
    android:id="@+id/fl_hot"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    />

title

<?xml version="1.0" encoding="utf-8"?>

<ImageView
    android:id="@+id/search_title"
    android:layout_width="20dp"
    android:layout_height="20dp"
    android:layout_centerVertical="true"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:background="@drawable/search"/>

<EditText
    android:id="@+id/edit_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="#000000"
    android:layout_toRightOf="@+id/search_title"/>

title_week

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"></LinearLayout>

控件

edit_bg

<?xml version="1.0" encoding="UTF-8"?>

attrs

<?xml version="1.0" encoding="utf-8"?>
<declare-styleable name="CustomTurntableView">
    <!-- name为属性的名字,可以随意起,只要符合规则看得懂 -->
    <!-- format为属性内容的类型 -->
    <attr name="text" format="string"></attr>
</declare-styleable>

<declare-styleable name="WeekFlowLayout">
    <attr name="textColor" format="color"></attr>
</declare-styleable>

TitleBarView 标题栏
public class TitleBarView extends LinearLayout {
Context mContext;

public TitleBarView(Context context) {
    super(context);
    mContext = context;
    init();
}

public TitleBarView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    mContext = context;
    init();
}

private void init() {
    //添加布局
    View view = View.inflate(mContext, R.layout.title, null);
    final EditText editText = view.findViewById(R.id.edit_title);
    view.findViewById(R.id.search_title).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            //第六步:在将要回调的地方,首先判断非空
            if(mOnButtonClickListener != null){
                //第七步:执行回调方法,传参
                mOnButtonClickListener.onButtonClick(editText.getText().toString());
            }
        }
    });
    addView(view);
}

//第三步:设置成员变量
OnBuutonClickListener mOnButtonClickListener;

//第四步:传入,并且给成员变量赋值
//第五步:在想要接受回调的地方,调用set方法,设置监听,详见WeekTestActivty #Line31
public void  setButtonClickListener(OnBuutonClickListener onBuutonClickListener){
    mOnButtonClickListener = onBuutonClickListener;
}

//第一步:定义一个接口
public interface OnBuutonClickListener{
    //第二步:写好方法和回传参数
    void onButtonClick(String str);
}

}

WeekTitleViewGroup
public class WeekTitleViewGroup extends LinearLayout{
Context mContext;

public WeekTitleViewGroup(Context context) {
    super(context);
    mContext = context;
}

public WeekTitleViewGroup(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    mContext = context;
    init();
}

private void init() {
    View view = View.inflate(mContext, R.layout.title_week, null);

}

}

WeekGroupNameLayout

@SuppressLint(“AppCompatCustomView”)
public class WeekGroupNameLayout extends TextView{
public WeekGroupNameLayout(Context context) {
super(context);
}

public WeekGroupNameLayout(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);

    //自定义属性
    //第一步,在value文件夹下建立一个attr.xml文件,
    //第二步,写<declear....标签
    //第三步,写<attr 标签 name:方法名 format:属性
    //第四步,在布局文件根控件中写xmlns:app="http://schemas.android.com/apk/res-auto"
    //第五步,在想要调用自定义属性的控件中添加app:方法名=“想要设置的值”
    //第六步,在自定义view中的有AttributeSet的构造方法里写以下代码
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WeekFlowLayout);
    int color = typedArray.getColor(R.styleable.WeekFlowLayout_textColor, Color.BLACK);

    setTextColor(color);

    //最后要回收
    typedArray.recycle();
}

}

WeekFlowLayout
public class WeekFlowLayout extends LinearLayout {
/**
* 孩子中最高的一个
*/
private int mChildMaxHeight;

/**
 * 每一个孩子的左右的间距
 * 20是默认值,单位是px
 */
private int mHSpace = 20;

/**
 * 每一行的上下的间距
 * 20是默认值,单位是px
 */
private int mVSpace = 20;


public WeekFlowLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    // 拿到父容器推荐的宽和高以及计算模式
    int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
    int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);

    //测量孩子的大小,一定要写这个
    measureChildren(widthMeasureSpec, heightMeasureSpec);

    //寻找孩子中最高的一个孩子,找到的值会放在mChildMaxHeight变量中
    findMaxChildMaxHeight();

    //初始化值
    int left = 0, top = 0;

    //循环所有的孩子
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        View view = getChildAt(i);
        //是否是一行的开头
        if (left != 0) {
            //需要换行了,因为放不下啦
            if ((left + view.getMeasuredWidth()) > sizeWidth) {
                //计算出下一行的top
                top += mChildMaxHeight + mVSpace;
                left = 0;
            }
        }
        left += view.getMeasuredWidth() + mHSpace;
    }
    setMeasuredDimension(sizeWidth, (top + mChildMaxHeight) > sizeHeight ? sizeHeight : top + mChildMaxHeight);

}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    findMaxChildMaxHeight();

    //开始安排孩子的位置

    //初始化值
    int left = 0, top = 0;

    //循环所有的孩子
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        View view = getChildAt(i);
        //是否是一行的开头
        if (left != 0) {
            //需要换行了,因为放不下啦
            if ((left + view.getMeasuredWidth()) > getWidth()) {
                //计算出下一行的top
                top += mChildMaxHeight + mVSpace;
                left = 0;
            }
        }

        //安排孩子的位置
        view.layout(left, top, left + view.getMeasuredWidth(), top + mChildMaxHeight);
        left += view.getMeasuredWidth() + mHSpace;
    }
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
}

/**
 * 寻找孩子中最高的一个孩子
 */
private void findMaxChildMaxHeight() {
    mChildMaxHeight = 0;
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        View view = getChildAt(i);
        if (view.getMeasuredHeight() > mChildMaxHeight) {
            mChildMaxHeight = view.getMeasuredHeight();
        }
    }
}

}

MainActivity

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    init();
}

private void init(){
    final WeekFlowLayout fl_search = findViewById(R.id.fl_search);
    WeekFlowLayout fl_hot = findViewById(R.id.fl_hot);

    TitleBarView title = findViewById(R.id.title);
    title.setButtonClickListener(new TitleBarView.OnBuutonClickListener() {
        @Override
        public void onButtonClick(final String str) {
            // 随机字符串,当作唯一标示
            UUID uuid = UUID.randomUUID();
            Log.i("dj", "创建时的UUID:" + uuid + " ,字符串是:" + str);
            TextView tv = new TextView(MainActivity.this);
            tv.setTag(uuid);
            tv.setTextColor(Color.RED);
            tv.setText(str);
            tv.setBackgroundResource(R.drawable.edit_bg);
            fl_search.addView(tv);

            tv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String uuid = String.valueOf(v.getTag());
                    Log.i("dj", "点击时的UUID:" + uuid + " ,字符串是:" + str);
                }
            });
        }
    });

    for(int i = 0; i < 30; i++){
        TextView tv = new TextView(MainActivity.this);
        tv.setText("数据 " + i);
        tv.setTextColor(Color.RED);
        tv.setBackgroundResource(R.drawable.edit_bg);
        fl_hot.addView(tv);
    }
}

}

猜你喜欢

转载自blog.csdn.net/FriggingAwesome/article/details/84652522