流式布局

来源:互联网 发布:白银交易软件 编辑:程序博客网 时间:2024/06/03 17:09
主activity布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:orientation="vertical"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:layout_height="match_parent" tools:context="com.example.qp.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="5dp"        android:orientation="horizontal">        <EditText            android:id="@+id/et_input"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:layout_weight="1"            android:hint="请输入你想搜索的内容"            android:maxLines="1"            android:paddingLeft="5dp"            android:paddingRight="5dp"/>        <Button            android:id="@+id/btn_search"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_margin="5dp"            android:text="搜索"/>    </LinearLayout>    <LinearLayout        android:id="@+id/layout_notice"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical"><com.example.qp.FlowLayout    android:id="@+id/flowlayout"    android:layout_width="match_parent"    android:layout_height="wrap_content"></com.example.qp.FlowLayout>        <LinearLayout            android:id="@+id/search_history_ll"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="vertical"            android:visibility="gone">            <TextView                android:id="@+id/contentTextView"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:paddingBottom="4dp"                android:paddingLeft="10dp"                android:paddingTop="4dp"                android:text="历史搜索"                android:textSize="12sp"/>            <ListView                android:id="@+id/search_history_lv"                android:layout_width="match_parent"                android:layout_height="wrap_content"                >            </ListView>            <Button                android:id="@+id/clear_history_btn"                android:layout_width="210dp"                android:layout_height="38dp"                android:layout_gravity="center"                android:layout_marginTop="5dp"                android:background="@drawable/round_btn_selector"                android:text="清除历史搜索记录"                android:textSize="14sp"/>        </LinearLayout>    </LinearLayout></LinearLayout>1
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/contentTextView"    android:layout_width="match_parent"    android:layout_height="51dp"    android:paddingLeft="10dp"    android:gravity="center_vertical"    android:background="@color/colorPrimary"    android:textSize="14sp"    android:textColor="#ff403b37"/>
2
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_margin="5dp"    android:background="@color/colorPrimary"    android:paddingBottom="10dp"    android:paddingLeft="20dp"    android:paddingRight="20dp"    android:paddingTop="10dp"    android:text="Helloworld"    android:textColor="#3f3e3e"    android:textSize="14sp">></TextView>
FlowLayout
package com.example.qp;import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;/** * author:Created by WangZhiQiang on 2017/12/19. */public class FlowLayout extends ViewGroup {    public FlowLayout(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    public FlowLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public FlowLayout(Context context) {        this(context, null);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);        int modeWidth = MeasureSpec.getMode(widthMeasureSpec);        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);        int modeHeight = MeasureSpec.getMode(heightMeasureSpec);        // 如果是warp_content情况下,记录宽和高        int width = 0;        int height = 0;        // 记录每一行的宽度与高度        int lineWidth = 0;        int lineHeight = 0;        // 得到内部元素的个数        int cCount = getChildCount();        for (int i = 0; i < cCount; i++) {            // 通过索引拿到每一个子view            View child = getChildAt(i);            // 测量子View的宽和高,系统提供的measureChild            measureChild(child, widthMeasureSpec, heightMeasureSpec);            // 得到LayoutParams            MarginLayoutParams lp = (MarginLayoutParams) child                    .getLayoutParams();            // 子View占据的宽度            int childWidth = child.getMeasuredWidth() + lp.leftMargin                    + lp.rightMargin;            // 子View占据的高度            int childHeight = child.getMeasuredHeight() + lp.topMargin                    + lp.bottomMargin;            // 换行 判断 当前的宽度大于 开辟新行            if (lineWidth + childWidth > sizeWidth - getPaddingLeft() - getPaddingRight()) {                // 对比得到最大的宽度                width = Math.max(width, lineWidth);                // 重置lineWidth                lineWidth = childWidth;                // 记录行高                height += lineHeight;                lineHeight = childHeight;            } else            // 未换行            {                // 叠加行宽                lineWidth += childWidth;                // 得到当前行最大的高度                lineHeight = Math.max(lineHeight, childHeight);            }            // 特殊情况,最后一个控件            if (i == cCount - 1) {                width = Math.max(lineWidth, width);                height += lineHeight;            }        }        setMeasuredDimension(                modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width + getPaddingLeft() + getPaddingRight(),                modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height + getPaddingTop() + getPaddingBottom()//        );    }    /**     * 存储所有的View     */    private List<List<View>> mAllViews = new ArrayList<List<View>>();    /**     * 每一行的高度     */    private List<Integer> mLineHeight = new ArrayList<Integer>();    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        mAllViews.clear();        mLineHeight.clear();        // 当前ViewGroup的宽度        int width = getWidth();        int lineWidth = 0;        int lineHeight = 0;        // 存放每一行的子view        List<View> lineViews = new ArrayList<View>();        int cCount = getChildCount();        for (int i = 0; i < cCount; 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 - getPaddingLeft() - getPaddingRight()) {                // 记录LineHeight                mLineHeight.add(lineHeight);                // 记录当前行的Views                mAllViews.add(lineViews);                // 重置我们的行宽和行高                lineWidth = 0;                lineHeight = childHeight + lp.topMargin + lp.bottomMargin;                // 重置我们的View集合                lineViews = new ArrayList<View>();            }            lineWidth += childWidth + lp.leftMargin + lp.rightMargin;            lineHeight = Math.max(lineHeight, childHeight + lp.topMargin                    + lp.bottomMargin);            lineViews.add(child);        }// for end        // 处理最后一行        mLineHeight.add(lineHeight);        mAllViews.add(lineViews);        // 设置子View的位置        int left = getPaddingLeft();        int top = getPaddingTop();        // 行数        int lineNum = mAllViews.size();        for (int i = 0; i < lineNum; i++) {            // 当前行的所有的View            lineViews = mAllViews.get(i);            lineHeight = mLineHeight.get(i);            for (int j = 0; j < lineViews.size(); j++) {                View child = lineViews.get(j);                // 判断child的状态                if (child.getVisibility() == View.GONE) {                    continue;                }                MarginLayoutParams lp = (MarginLayoutParams) child                        .getLayoutParams();                int lc = left + lp.leftMargin;                int tc = top + lp.topMargin;                int rc = lc + child.getMeasuredWidth();                int bc = tc + child.getMeasuredHeight();                // 为子View进行布局                child.layout(lc, tc, rc, bc);                left += child.getMeasuredWidth() + lp.leftMargin                        + lp.rightMargin;            }            left = getPaddingLeft();            top += lineHeight;        }    }    /**     * 与当前ViewGroup对应的LayoutParams     */    @Override    public LayoutParams generateLayoutParams(AttributeSet attrs) {        return new MarginLayoutParams(getContext(), attrs);    }}
主activity
package com.example.qp;import android.app.Activity;import android.content.SharedPreferences;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.text.Editable;import android.text.TextUtils;import android.text.TextWatcher;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private FlowLayout mFlowLayout;    private LayoutInflater mInflater;    private String[] mVals = new String[]{"Java", "Android", "iOS", "Python",            "Mac OS", "PHP", "JavaScript", "Objective-C",            "Groovy", "Pascal", "Ruby", "Go", "Swift"};//数据模拟,实际应从网络获取此数据    /************     * 以上为流式标签相关     ************/    public static final String EXTRA_KEY_TYPE = "extra_key_type";    public static final String EXTRA_KEY_KEYWORD = "extra_key_keyword";    public static final String KEY_SEARCH_HISTORY_KEYWORD = "key_search_history_keyword";    private SharedPreferences mPref;//使用SharedPreferences记录搜索历史    private String mType;    private EditText input;    private Button btn_search;    private List<String> mHistoryKeywords;//记录文本    private ArrayAdapter<String> mArrAdapter;//搜索历史适配器    private LinearLayout mSearchHistoryLl;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initFlowView();        initHistoryView();    }    private void initFlowView() {        mInflater = LayoutInflater.from(this);        mFlowLayout = (FlowLayout) findViewById(R.id.flowlayout);        initData();    }    /**     * 将数据放入流式布局     */    private void initData() {        for (int i = 0; i < mVals.length; i++) {            TextView tv = (TextView) mInflater.inflate(                    R.layout.search_lable_tv, mFlowLayout, false);            tv.setText(mVals[i]);            final String str = tv.getText().toString();            //点击事件            tv.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    //加入搜索历史纪录记录                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();                }            });            mFlowLayout.addView(tv);        }    }    /************     * 以上为流式标签相关     ************/    private void initHistoryView() {        input = (EditText) findViewById(R.id.et_input);        btn_search = (Button) findViewById(R.id.btn_search);        btn_search.setOnClickListener(this);        mPref = getSharedPreferences("input", Activity.MODE_PRIVATE);        mType = getIntent().getStringExtra(EXTRA_KEY_TYPE);        String keyword = getIntent().getStringExtra(EXTRA_KEY_KEYWORD);        if (!TextUtils.isEmpty(keyword)) {            input.setText(keyword);        }        mHistoryKeywords = new ArrayList<String>();        input = (EditText) findViewById(R.id.et_input);        input.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                if (s.length() == 0) {                    if (mHistoryKeywords.size() > 0) {                        mSearchHistoryLl.setVisibility(View.VISIBLE);                    } else {                        mSearchHistoryLl.setVisibility(View.GONE);                    }                } else {                    mSearchHistoryLl.setVisibility(View.GONE);                }            }            @Override            public void afterTextChanged(Editable s) {            }        });        initSearchHistory();    }    /**     * 初始化搜索历史记录     */    public void initSearchHistory() {        mSearchHistoryLl = (LinearLayout) findViewById(R.id.search_history_ll);        ListView listView = (ListView) findViewById(R.id.search_history_lv);        findViewById(R.id.clear_history_btn).setOnClickListener(this);        String history = mPref.getString(KEY_SEARCH_HISTORY_KEYWORD, "");        if (!TextUtils.isEmpty(history)) {            List<String> list = new ArrayList<String>();            for (Object o : history.split(",")) {                list.add((String) o);            }            mHistoryKeywords = list;        }        if (mHistoryKeywords.size() > 0) {            mSearchHistoryLl.setVisibility(View.VISIBLE);        } else {            mSearchHistoryLl.setVisibility(View.GONE);        }        mArrAdapter = new ArrayAdapter<String>(this, R.layout.item_search_history, mHistoryKeywords);        listView.setAdapter(mArrAdapter);        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {                input.setText(mHistoryKeywords.get(i));                mSearchHistoryLl.setVisibility(View.GONE);            }        });        mArrAdapter.notifyDataSetChanged();    }    /**     * 储存搜索历史     */    public void save() {        String text = input.getText().toString();        String oldText = mPref.getString(KEY_SEARCH_HISTORY_KEYWORD, "");        Log.e("tag", "" + oldText);        Log.e("Tag", "" + text);        Log.e("Tag", "" + oldText.contains(text));        if (!TextUtils.isEmpty(text) && !(oldText.contains(text))) {            if (mHistoryKeywords.size() > 5) {                //最多保存条数                return;            }            SharedPreferences.Editor editor = mPref.edit();            editor.putString(KEY_SEARCH_HISTORY_KEYWORD, text + "," + oldText);            editor.commit();            mHistoryKeywords.add(0, text);        }        mArrAdapter.notifyDataSetChanged();    }    /**     * 清除历史纪录     */    public void cleanHistory() {        mPref = getSharedPreferences("input", MODE_PRIVATE);        SharedPreferences.Editor editor = mPref.edit();        editor.remove(KEY_SEARCH_HISTORY_KEYWORD).commit();        mHistoryKeywords.clear();        mArrAdapter.notifyDataSetChanged();        mSearchHistoryLl.setVisibility(View.GONE);        Toast.makeText(MainActivity.this, "清楚搜索历史成功", Toast.LENGTH_LONG).show();    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn_search:                String keywords = input.getText().toString();                if (!TextUtils.isEmpty(keywords)) {                    Toast.makeText(MainActivity.this, keywords + "save成功", Toast.LENGTH_LONG).show();                    save();                } else {                    Toast.makeText(MainActivity.this, "请输入搜索内容", Toast.LENGTH_LONG).show();                }                break;            case R.id.clear_history_btn:                cleanHistory();                break;            default:                break;        }    }}

原创粉丝点击