布局
activity_main
<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);
}
}
}