自定义ViewGroup之TagLayout

来源:互联网 发布:sha-256算法 编辑:程序博客网 时间:2024/05/29 09:55

今天抽空写了一个标签布局,这里为了简单起见,我忽略了onMeasure方法,默认使用屏幕宽度和计算出来的高度作为当前TagLayout的宽度和高度,今天不想写太多话,所以直接上代码了

流式布局简单实现

创建TagLayout

public class TagLayout extends ViewGroup {    private int mScreenWidth;    public TagLayout(Context context) {        this(context, null);    }    public TagLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public TagLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        mScreenWidth = wm.getDefaultDisplay().getWidth();    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        int totalHeight = 0;        int totalWidth = 0;        View currentChild;        int marginLeft = 0;        int marginRight = 0;        int marginTop = 0;        int currentWidth = 0;        int currentHeight = 0;        int maxHeight = 0;        LinearLayout.MarginLayoutParams marginLayoutParams = null;        for (int i= 0; i < getChildCount(); i++) {            currentChild = getChildAt(i); //记录当前view            // 获取当前view的外边距            marginLayoutParams = (MarginLayoutParams) currentChild.getLayoutParams();            marginLeft = marginLayoutParams.leftMargin;            marginRight = marginLayoutParams.rightMargin;            marginTop = marginLayoutParams.topMargin;            // 获取当前view的宽度和高度            currentWidth = currentChild.getMeasuredWidth();            currentHeight = currentChild.getMeasuredHeight();            if (currentHeight > maxHeight) {                maxHeight = currentHeight;            }            // 如果 "当前已有的宽度 + 当前view的宽度 > 屏幕的宽度",则需要重新开启一行            if (currentWidth + marginLeft + marginRight + totalWidth > mScreenWidth) { // a new line                totalWidth = 0;                totalHeight = totalHeight + maxHeight + marginTop;                currentChild.layout(totalWidth + marginLeft,totalHeight + marginTop,totalWidth + marginLeft + currentWidth,totalHeight + marginTop + currentHeight);                // 重新为totalWidth赋值,需要新行里绘制的第一个子的宽度计算在里面                totalWidth = totalWidth + currentWidth + marginLeft;            } else {                currentChild.layout(totalWidth + marginLeft,totalHeight + marginTop,totalWidth + marginLeft + currentWidth,totalHeight + marginTop + currentHeight);                // 重新计算当前已有的宽度                totalWidth += currentWidth + marginRight;            }        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        // 测量所有子view        measureChildren(widthMeasureSpec, heightMeasureSpec);        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    public LayoutParams generateLayoutParams(AttributeSet attrs) {        // 子view使用MarginLayoutParams        return new LinearLayout.MarginLayoutParams(getContext(),attrs);    }}

布局中使用

<?xml version="1.0" encoding="utf-8"?><com.example.taglayout.TagLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content">    <Button        android:layout_width="wrap_content"        android:layout_height="60dp"        android:layout_margin="10dp"        android:text="Hello World!" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:text="Hello Worldaaaa!" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:text="Hello World!ddddadfgsadfasd" />    <Button        android:layout_width="wrap_content"        android:layout_height="60dp"        android:layout_margin="10dp"        android:text="abcdefghijklmn" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:text="Hello!" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:text="Hel" /></com.example.taglayout.TagLayout>

此时效果如下:
这里写图片描述

给每一个tag添加背景

这里可以使用shape标签,创建一个圆角矩形

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#99CCFF" />    <corners android:topLeftRadius="20dp"        android:topRightRadius="20dp"        android:bottomRightRadius="20dp"        android:bottomLeftRadius="20dp"/>    <stroke android:width="1dp" android:color="#000000" /></shape>

在布局中使用背景

<?xml version="1.0" encoding="utf-8"?><com.example.taglayout.TagLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:padding="10dp"        android:text="Hello World!"        android:background="@drawable/tag_background"        />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:padding="10dp"        android:text="Hello Worldaaaa!"        android:background="@drawable/tag_background"        />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:padding="10dp"        android:text="Hello World!ddddadfgsadfasd"        android:background="@drawable/tag_background"        />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:padding="10dp"        android:text="abcdefghijklmn"        android:background="@drawable/tag_background"        />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:padding="10dp"        android:text="Hello!"        android:background="@drawable/tag_background"        />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:padding="10dp"        android:text="Hel"        android:background="@drawable/tag_background"        /></com.example.taglayout.TagLayout>

此时效果如下:
这里写图片描述

动态添加效果

定义一个类似于search的布局,每次搜索,都将该字符串动态添加到TagLayout

SearchLayout

public class SearchLayout extends LinearLayout implements EditInterface, View.OnClickListener {    public SearchLayout(Context context) {        this(context, null);    }    public SearchLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    // 文本框    EditText mEditText = null;    // 删除提示    TextView mTextView = null;    Button mSubmitBtn = null;    TagLayout mTagLayout = null;    public SearchLayout(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        final LayoutInflater layoutInflater = LayoutInflater.from(context);        layoutInflater.inflate(R.layout.search_layout, this, true);        mEditText = (EditText) findViewById(R.id.edittext);        mTextView = (TextView) findViewById(R.id.textview);        mSubmitBtn = (Button) findViewById(R.id.id_search);        mTagLayout = (TagLayout) findViewById(R.id.id_taglayout);        mEditText.addTextChangedListener(new TextWatcher() {            @Override            public void onTextChanged(CharSequence s, int start, int abefore, int count) {            }            @Override            public void beforeTextChanged(CharSequence s, int start, int count,                                          int after) {            }            @Override            public void afterTextChanged(Editable s) {                // 根据当前的内容是否==""来决定是否显示删除文字                if (s != null && s.length() == 0) {                    hiddenCancel();                } else {                    showCancel();                }            }        });        mTextView.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                mEditText.setText("");            }        });        // 当点击提交的时候,动态将该搜索的字符添加到该布局中        mSubmitBtn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                TextView searchText = new TextView(getContext());                searchText.setText(mEditText.getText().toString());                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);                searchText.setLayoutParams(params);                searchText.setBackground(getContext().getResources().getDrawable(R.drawable.tag_background));                int paddingOrMargin = dp2px(getContext(),10f);                params.leftMargin = paddingOrMargin;                params.topMargin = paddingOrMargin;                params.rightMargin = paddingOrMargin;                params.bottomMargin = paddingOrMargin;                searchText.setPadding(paddingOrMargin, paddingOrMargin, paddingOrMargin, paddingOrMargin);                // 每添加一个view设置其点击事件                searchText.setOnClickListener(SearchLayout.this);                mTagLayout.addView(searchText,params);                mTagLayout.requestLayout();            }        });        // 设置事件监听        int childCount = mTagLayout.getChildCount();        View childTagView = null;        for (int i = 0; i < childCount; i ++) {            childTagView = mTagLayout.getChildAt(i);            childTagView.setOnClickListener(this);        }    }    public static int dp2px(Context context, float dpVal)    {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,                dpVal, context.getResources().getDisplayMetrics());    }    @Override    public void hiddenCancel() {        mTextView.setVisibility(View.GONE);    }    @Override    public void showCancel() {        mTextView.setVisibility(View.VISIBLE);    }    @Override    public void onClick(View v) {        mEditText.setText(((TextView)v).getText().toString());    }}// 自己定义接口,用来控制显示和隐藏当前删除按钮interface EditInterface {    public void hiddenCancel();    public void showCancel();}

创建SearchLayout引用的布局

<?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="wrap_content"    android:orientation="vertical"    >    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <EditText            android:id="@+id/edittext"            android:layout_width="0dp"            android:layout_height="100dp"            android:layout_weight="4"            android:singleLine="true" />        <TextView            android:id="@+id/textview"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:clickable="true"            android:text="删除"            android:textColor="#ff0000"            android:visibility="invisible" />        <Button            android:id="@+id/id_search"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="2"            android:text="搜索"            />    </LinearLayout>    <com.example.taglayout.TagLayout        android:id="@+id/id_taglayout"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="10dp"        >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_margin="10dp"            android:padding="10dp"            android:text="Hello World!"            android:background="@drawable/tag_background"            />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_margin="10dp"            android:padding="10dp"            android:text="一个神器的网站"            android:background="@drawable/tag_background"            />            />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_margin="10dp"            android:padding="10dp"            android:text="你不是真正的快乐"            android:background="@drawable/tag_background"            />    </com.example.taglayout.TagLayout></LinearLayout>

在主布局中使用SearchLayout

<?xml version="1.0" encoding="utf-8"?><com.example.taglayout.SearchLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical"    ></com.example.taglayout.SearchLayout>

此时效果如下:
这里写图片描述

今天就到这了,不想说太多话,源码下载

0 0
原创粉丝点击