仿今日头条添加导航栏标签的方式。首先添加标签的时候需要根据标签长度确定每一行放几个,这个得自定义一个viewGroup实现,通过addView方式添加TextView控件,并且给没个TextView设置tag方便事件监听,自定义ViewGroup如下:
public class LabelLayout extends ViewGroup {
//存储所有子View
private List<List<View>> mAllChildViews = new ArrayList<>();
//每一行的高度
private List<Integer> mLineHeight = new ArrayList<>();
public LabelLayout(Context context) {
this(context, null);
}
public LabelLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LabelLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//父控件传进来的宽度和高度以及对应的测量模式
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
//如果当前ViewGroup的宽高为wrap_content的情况
int width = 0;//自己测量的 宽度
int height = 0;//自己测量的高度
//记录每一行的宽度和高度
int lineWidth = 0;
int lineHeight = 0;
int row = 1;
//获取子view的个数
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
//测量子View的宽和高
measureChild(child, widthMeasureSpec, heightMeasureSpec);
//得到LayoutParams
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
//子View占据的宽度
int childWidth = child.getMeasuredWidth() + lp.leftMargin ;
//子View占据的高度
int childHeight = child.getMeasuredHeight() + lp.topMargin;
height = child.getMeasuredHeight()+lp.topMargin;
//换行时候
if (lineWidth + childWidth > sizeWidth) {
//对比得到最大的宽度
width = Math.max(width, lineWidth);
//重置lineWidth
lineWidth = childWidth;
//记录行高
//height += lineHeight;
lineHeight = childHeight;
row++;
} else {//不换行情况
//叠加行宽
lineWidth += childWidth;
//得到最大行高
lineHeight = Math.max(lineHeight, childHeight);
}
//处理最后一个子View的情况
if (i == childCount - 1) {
width = Math.max(width, lineWidth);
}
}
//wrap_content
setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width,row * height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mAllChildViews.clear();
mLineHeight.clear();
//获取当前ViewGroup的宽度
int width = getWidth();
int lineWidth = 0;
int lineHeight = 0;
//记录当前行的view
List<View> lineViews = new ArrayList<>();
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
//如果需要换行
if (childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width) {
//记录LineHeight
mLineHeight.add(lineHeight);
//记录当前行的Views
mAllChildViews.add(lineViews);
//重置行的宽高
lineWidth = 0;
lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
//重置view的集合
lineViews = new ArrayList();
}
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
lineViews.add(child);
}
//处理最后一行
mLineHeight.add(lineHeight);
mAllChildViews.add(lineViews);
//设置子View的位置
int left = 0;
int top = 0;
//获取行数
int lineCount = mAllChildViews.size();
for (int i = 0; i < lineCount; i++) {
//当前行的views和高度
lineViews = mAllChildViews.get(i);
lineHeight = mLineHeight.get(i);
for (int j = 0; j < lineViews.size(); j++) {
View child = lineViews.get(j);
//判断是否显示
if (child.getVisibility() == View.GONE) {
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int cLeft = left + lp.leftMargin;
int cTop = top + lp.topMargin;
int cRight = cLeft + child.getMeasuredWidth();
int cBottom = cTop + child.getMeasuredHeight();
//进行子View进行布局
child.layout(cLeft, cTop, cRight, cBottom);
left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
left = 0;
top += lineHeight;
}
}
/**
* 与当前ViewGroup对应的LayoutParams
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
}
复制代码
xml中引用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F0F0F0"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:text="我的关注" />
<com.eebbk.draglistviewtest.view.LabelLayout
android:id="@+id/flow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:animateLayoutChanges="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:text="全部产品" />
<com.eebbk.draglistviewtest.view.LabelLayout
android:id="@+id/flow_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:animateLayoutChanges="true" />
</LinearLayout>
复制代码
下面是Activity中使用方法:
public class HomeActivity extends AppCompatActivity implements View.OnClickListener {
private String lableName[] = {"广发可选消费ETF", "上证物联网",
"恒生电子", "物联世界", "恒生期货", "恒生现金宝"
};
private String lableName1[] = {"恒生价值精选",
"恒生混合平衡", "恒生债券", "广发证券"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
initData();
initView();
}
public void initData() {
}
LabelLayout labelLayout, labelLayoutall;
MarginLayoutParams lp;
private void initView() {
lp = new MarginLayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.leftMargin = 5;
lp.rightMargin = 5;
lp.topMargin = 5;
lp.bottomMargin = 5;
labelLayout = (LabelLayout) findViewById(R.id.flow);
labelLayoutall = (LabelLayout) findViewById(R.id.flow_all);
for (String aLableName : lableName) {
TextView view = new TextView(this);
view.setText(aLableName);
view.setBackgroundDrawable(getResources().getDrawable(shape_file_pressed));
view.setTag("up");
labelLayout.addView(view, lp);
view.setOnClickListener(this);
}
for (String aLableName : lableName1) {
TextView view = new TextView(this);
view.setText(aLableName);
view.setBackgroundDrawable(getResources().getDrawable(shape_file_pressed));
view.setTag("down");
labelLayoutall.addView(view, lp);
view.setOnClickListener(this);
}
}
@Override
public void onClick(View view) {
String txt = ((TextView) view).getText().toString();
if (view.getTag().equals("up")) {
labelLayout.removeView(view);
labelLayout.invalidate();
TextView view1 = new TextView(this);
view1.setText(txt);
view1.setBackgroundDrawable(getResources().getDrawable(shape_file_pressed));
view1.setTag("down");
view1.setOnClickListener(this);
labelLayoutall.addView(view1, lp);
labelLayoutall.invalidate();
} else if (view.getTag().equals("down")) {
labelLayoutall.removeView(view);
labelLayoutall.invalidate();
TextView view1 = new TextView(this);
view1.setText(txt);
view1.setBackgroundDrawable(getResources().getDrawable(shape_file_pressed));
view1.setTag("up");
view1.setOnClickListener(this);
labelLayout.addView(view1, lp);
labelLayout.invalidate();
}
}
}
复制代码