流式布局

来源:互联网 发布:Linux check_match 编辑:程序博客网 时间:2024/06/08 02:02

activity_sou_suo.xml布局

<?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"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:id="@+id/ss"        android:orientation="horizontal"        android:layout_height="80dp"        android:layout_width="match_parent"        android:background="#b53232">    <Button        android:id="@+id/ssfinish"        android:layout_height="30dp"        android:layout_width="30dp"        android:background="@mipmap/leftjian"        android:layout_marginTop="15dp"        android:layout_marginLeft="10dp"        android:layout_marginBottom="15dp"/>    <EditText        android:id="@+id/edt"        android:layout_height="wrap_content"        android:layout_width="0dp"        android:background="@drawable/shape002"        android:layout_marginTop="5dp"        android:layout_marginLeft="10dp"        android:layout_marginBottom="5dp"        android:textSize="15dp"        android:textColor="#000"        android:hint="请输入搜索内容"        android:layout_weight="1"        android:layout_marginRight="10dp"        android:layout_gravity="center"/>    <Button        android:id="@+id/btn"        android:layout_height="40dp"        android:layout_width="60dp"        android:background="#fff"        android:layout_marginTop="15dp"        android:layout_marginBottom="10dp"        android:textSize="20dp"        android:layout_marginRight="20dp"        android:text="搜索"/></LinearLayout>    <TextView        android:layout_marginTop="15dp"        android:layout_marginLeft="10dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="热门搜索"        />    <LinearLayout        android:layout_marginTop="20dp"        android:layout_marginLeft="15dp"        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content">    <Button        android:text="RxIava"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <Button        android:text="RxAndroid"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />        <Button            android:text="数据库"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <Button            android:text="自定义控件"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />    </LinearLayout>    <LinearLayout        android:layout_marginLeft="15dp"        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <Button            android:text="下拉刷新上拉加载"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <Button            android:text="mvp"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <Button            android:text="直播"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <Button            android:text="权限管理"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />    </LinearLayout>    <LinearLayout        android:layout_marginLeft="15dp"        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <Button            android:text="Retrofit框架"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <Button            android:text="OkHttp"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <Button            android:text="WebView"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <Button            android:text="热修复"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />    </LinearLayout>    <LinearLayout        android:orientation="horizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content">   <TextView       android:layout_width="wrap_content"       android:layout_height="wrap_content"       android:text="历史记录"       android:textSize="17dp"       android:layout_marginTop="15dp"       android:layout_marginLeft="10dp"       />        <ImageView            android:id="@+id/shanchu"            android:src="@mipmap/rublish"            android:layout_width="30dp"            android:layout_height="30dp"            android:layout_marginTop="15dp"            android:layout_marginLeft="330dp"            />    </LinearLayout>    <ScrollView        android:layout_width="match_parent"        android:layout_height="match_parent">        <com.bwei.lgank.myview.TagFlowLayout            android:layout_marginTop="30dp"            android:id="@+id/id_flowlayout"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            app:max_select="-1" />    </ScrollView></LinearLayout>tv.xml
<?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_marginLeft="5dp"    android:layout_marginRight="5dp"    android:layout_marginTop="10dp"    android:background="@drawable/tag_bg"    android:text="Helloworld"    android:textColor="#999999"    android:textSize="14dp"></TextView>drawable下的文件夹border002.xml
<?xml version="1.0" encoding="UTF-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <stroke android:color="#000" android:width="0.05dp"/>    <padding/></shape>


checked_bg.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#ffffff" />    <corners android:radius="2dp" />    <stroke        android:width="1dp"        android:color="#dddddd" />    <padding        android:bottom="5dp"        android:left="14dp"        android:right="14dp"        android:top="5dp" /></shape>


normal_bg.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#ffffff" />    <corners android:radius="2dp" />    <stroke        android:width="1dp"        android:color="#dddddd" />    <padding        android:bottom="5dp"        android:left="14dp"        android:right="14dp"        android:top="5dp" /></shape>


shape001.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#ffffff"/>    <!--设置按钮四个角为弧形-->    <!--android:radius弧形的半径-->    <corners android:radius="10dip"/>    <!--padding;button里面的文字与button边界的间隔-->    <padding android:top="10dp" android:right="10dp" android:left="10dp" android:bottom="10dp"/></shape>

shape002.xml


<?xml version="1.0" encoding="UTF-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#ffffff"/>    <!--设置按钮四个角为弧形-->    <!--android:radius弧形的半径-->    <corners android:radius="50dip"/>    <!--padding;button里面的文字与button边界的间隔-->    <padding android:top="10dp" android:right="10dp" android:left="10dp" android:bottom="10dp"/></shape>tag_bg.xml
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/checked_bg" android:state_checked="true">    </item>    <item android:drawable="@drawable/normal_bg"></item></selector>




values下的文件夹

attrs,xml


<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="TagFlowLayout">        <attr name="auto_select_effect" format="boolean"></attr>        <attr name="max_select" format="integer"></attr>        <attr name="gravity">            <enum name="left" value="-1" />            <enum name="center" value="0" />            <enum name="right" value="1" />        </attr>    </declare-styleable></resources>


colors.xml


<?xml version="1.0" encoding="utf-8"?><resources>    <color name="colorPrimary">#3F51B5</color>    <color name="colorPrimaryDark">#303F9F</color>    <color name="colorAccent">#FF4081</color>    <color name="kxb">#ff00</color>    <color name="hui">#ff888888</color>    <color name="huang">#F8F8FF00</color>    <color name="lv">#ff00ff00</color>    <color name="qing">#00FFFF</color>    <color name="lan">#ff0000ff</color>    <color name="zi">#ffff00ff</color></resources>


styles.xml

<resources>    <!-- Base application theme. -->    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>    </style></resources>



strings.xml


<resources>    <string name="app_name">LGank</string></resources>




SouSuoActivity.java类


import android.os.Build;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.view.LayoutInflater;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import android.widget.Toast;import com.bwei.lgank.R;import com.bwei.lgank.adapter.TagAdapter;import com.bwei.lgank.bean.ColorBean;import com.bwei.lgank.sp;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;import java.util.ArrayList;import java.util.List;public class SouSuoActivity extends AppCompatActivity {    private int color;    private TagFlowLayout mFlowLayout;    private EditText editText;    private Button button;    private List<String> strings;    //布局管理器    private LayoutInflater mInflater;    //流式布局的子布局    private TextView tv;    public Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case 1:                    mFlowLayout.setAdapter(new TagAdapter<String>(strings) {                        @Override                        public View getView(FlowLayout parent, int position, String s) {                            tv = (TextView) mInflater.inflate(R.layout.tv,                                    mFlowLayout, false);                            tv.setText(s);                            return tv;                        }                    });                    break;            }            super.handleMessage(msg);        }    };    private LinearLayout ss;    private ImageView shanchu;    private Button ssfinish;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Window window = getWindow();        getSupportActionBar().hide();        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            //透明状态栏            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);            //透明导航栏            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);        }        setContentView(R.layout.activity_sou_suo);        mInflater = LayoutInflater.from(this);        EventBus.getDefault().register(this);        ss = (LinearLayout) findViewById(R.id.ss);        Object color = sp.getData(SouSuoActivity.this, "color", R.color.kxb);        ss.setBackgroundColor((Integer) color);        mFlowLayout = (TagFlowLayout) findViewById(R.id.id_flowlayout);        editText = (EditText) findViewById(R.id.edt);        button = (Button) findViewById(R.id.btn);        strings = new ArrayList<>();        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                String aa = editText.getText().toString().trim();                strings.add(aa);                editText.getText().clear();                //通知handler更新UI                handler.sendEmptyMessageDelayed(1, 0);            }        });        shanchu = (ImageView) findViewById(R.id.shanchu);        shanchu.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                strings.clear();                handler.sendEmptyMessageDelayed(1, 0);            }        });        ssfinish = (Button) findViewById(R.id.ssfinish);        ssfinish.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                finish();            }        });        //流式布局tag的点击方法        mFlowLayout.setOnTagClickListener(new TagFlowLayout.OnTagClickListener() {            @Override            public boolean onTagClick(View view, int position, FlowLayout parent) {                Toast.makeText(SouSuoActivity.this, tv.getText(), Toast.LENGTH_SHORT).show();                return true;            }        });    }    @Subscribe(sticky = true,threadMode = ThreadMode.MAIN)    public void onEvent(ColorBean colorBean){        color =colorBean.getColor();    }    @Override    public void onDestroy() {        super.onDestroy();        EventBus.getDefault().unregister(this);    }}



TagFlowLayout类


import android.content.Context;import android.content.res.TypedArray;import android.graphics.Rect;import android.os.Bundle;import android.os.Parcelable;import android.text.TextUtils;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import com.bwei.lgank.R;import com.bwei.lgank.adapter.TagAdapter;import java.util.HashSet;import java.util.Iterator;import java.util.Set;/** * Created by zhy on 15/9/10. */public class TagFlowLayout extends FlowLayout implements TagAdapter.OnDataChangedListener {    private TagAdapter mTagAdapter;    private boolean mAutoSelectEffect = true;    private int mSelectedMax = -1;//-1为不限制数量    private static final String TAG = "TagFlowLayout";    private MotionEvent mMotionEvent;    private Set<Integer> mSelectedView = new HashSet<Integer>();    public TagFlowLayout(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TagFlowLayout);        mAutoSelectEffect = ta.getBoolean(R.styleable.TagFlowLayout_auto_select_effect, true);        mSelectedMax = ta.getInt(R.styleable.TagFlowLayout_max_select, -1);        ta.recycle();        if (mAutoSelectEffect) {            setClickable(true);        }    }    public TagFlowLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public TagFlowLayout(Context context) {        this(context, null);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int cCount = getChildCount();        for (int i = 0; i < cCount; i++) {            TagView tagView = (TagView) getChildAt(i);            if (tagView.getVisibility() == View.GONE) continue;            if (tagView.getTagView().getVisibility() == View.GONE) {                tagView.setVisibility(View.GONE);            }        }        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    public interface OnSelectListener {        void onSelected(Set<Integer> selectPosSet);    }    private OnSelectListener mOnSelectListener;    public void setOnSelectListener(OnSelectListener onSelectListener) {        mOnSelectListener = onSelectListener;        if (mOnSelectListener != null) setClickable(true);    }    public interface OnTagClickListener {        boolean onTagClick(View view, int position, FlowLayout parent);    }    private OnTagClickListener mOnTagClickListener;    public void setOnTagClickListener(OnTagClickListener onTagClickListener) {        mOnTagClickListener = onTagClickListener;        if (onTagClickListener != null) setClickable(true);    }    public void setAdapter(TagAdapter adapter) {        mTagAdapter = adapter;        mTagAdapter.setOnDataChangedListener(this);        mSelectedView.clear();        changeAdapter();    }    private void changeAdapter() {        removeAllViews();        TagAdapter adapter = mTagAdapter;        TagView tagViewContainer = null;        HashSet preCheckedList = mTagAdapter.getPreCheckedList();        for (int i = 0; i < adapter.getCount(); i++) {            View tagView = adapter.getView(this, i, adapter.getItem(i));            tagViewContainer = new TagView(getContext());//            ViewGroup.MarginLayoutParams clp = (ViewGroup.MarginLayoutParams) tagView.getLayoutParams();//            ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(clp);//            lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;//            lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;//            lp.topMargin = clp.topMargin;//            lp.bottomMargin = clp.bottomMargin;//            lp.leftMargin = clp.leftMargin;//            lp.rightMargin = clp.rightMargin;            tagView.setDuplicateParentStateEnabled(true);            if (tagView.getLayoutParams() != null) {                tagViewContainer.setLayoutParams(tagView.getLayoutParams());            } else {                MarginLayoutParams lp = new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);                lp.setMargins(dip2px(getContext(), 5),                        dip2px(getContext(), 5),                        dip2px(getContext(), 5),                        dip2px(getContext(), 5));                tagViewContainer.setLayoutParams(lp);            }            tagViewContainer.addView(tagView);            addView(tagViewContainer);            if (preCheckedList.contains(i)) {                tagViewContainer.setChecked(true);            }            if (mTagAdapter.setSelected(i, adapter.getItem(i))) {                mSelectedView.add(i);                tagViewContainer.setChecked(true);            }        }        mSelectedView.addAll(preCheckedList);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        if (event.getAction() == MotionEvent.ACTION_UP) {            mMotionEvent = MotionEvent.obtain(event);        }        return super.onTouchEvent(event);    }    @Override    public boolean performClick() {        if (mMotionEvent == null) return super.performClick();        int x = (int) mMotionEvent.getX();        int y = (int) mMotionEvent.getY();        mMotionEvent = null;        TagView child = findChild(x, y);        int pos = findPosByView(child);        if (child != null) {            doSelect(child, pos);            if (mOnTagClickListener != null) {                return mOnTagClickListener.onTagClick(child.getTagView(), pos, this);            }        }        return true;    }    public void setMaxSelectCount(int count) {        if (mSelectedView.size() > count) {            Log.w(TAG, "you has already select more than " + count + " views , so it will be clear .");            mSelectedView.clear();        }        mSelectedMax = count;    }    public Set<Integer> getSelectedList() {        return new HashSet<Integer>(mSelectedView);    }    private void doSelect(TagView child, int position) {        if (mAutoSelectEffect) {            if (!child.isChecked()) {                //处理max_select=1的情况                if (mSelectedMax == 1 && mSelectedView.size() == 1) {                    Iterator<Integer> iterator = mSelectedView.iterator();                    Integer preIndex = iterator.next();                    TagView pre = (TagView) getChildAt(preIndex);                    pre.setChecked(false);                    child.setChecked(true);                    mSelectedView.remove(preIndex);                    mSelectedView.add(position);                } else {                    if (mSelectedMax > 0 && mSelectedView.size() >= mSelectedMax)                        return;                    child.setChecked(true);                    mSelectedView.add(position);                }            } else {                child.setChecked(false);                mSelectedView.remove(position);            }            if (mOnSelectListener != null) {                mOnSelectListener.onSelected(new HashSet<Integer>(mSelectedView));            }        }    }    public TagAdapter getAdapter() {        return mTagAdapter;    }    private static final String KEY_CHOOSE_POS = "key_choose_pos";    private static final String KEY_DEFAULT = "key_default";    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable(KEY_DEFAULT, super.onSaveInstanceState());        String selectPos = "";        if (mSelectedView.size() > 0) {            for (int key : mSelectedView) {                selectPos += key + "|";            }            selectPos = selectPos.substring(0, selectPos.length() - 1);        }        bundle.putString(KEY_CHOOSE_POS, selectPos);        return bundle;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if (state instanceof Bundle) {            Bundle bundle = (Bundle) state;            String mSelectPos = bundle.getString(KEY_CHOOSE_POS);            if (!TextUtils.isEmpty(mSelectPos)) {                String[] split = mSelectPos.split("\\|");                for (String pos : split) {                    int index = Integer.parseInt(pos);                    mSelectedView.add(index);                    TagView tagView = (TagView) getChildAt(index);                    if (tagView != null)                        tagView.setChecked(true);                }            }            super.onRestoreInstanceState(bundle.getParcelable(KEY_DEFAULT));            return;        }        super.onRestoreInstanceState(state);    }    private int findPosByView(View child) {        final int cCount = getChildCount();        for (int i = 0; i < cCount; i++) {            View v = getChildAt(i);            if (v == child) return i;        }        return -1;    }    private TagView findChild(int x, int y) {        final int cCount = getChildCount();        for (int i = 0; i < cCount; i++) {            TagView v = (TagView) getChildAt(i);            if (v.getVisibility() == View.GONE) continue;            Rect outRect = new Rect();            v.getHitRect(outRect);            if (outRect.contains(x, y)) {                return v;            }        }        return null;    }    @Override    public void onChanged() {        mSelectedView.clear();        changeAdapter();    }    public static int dip2px(Context context, float dpValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dpValue * scale + 0.5f);    }}TagView类 
import android.content.Context;import android.view.View;import android.widget.Checkable;import android.widget.FrameLayout;/** * Created by zhy on 15/9/10. */public class TagView extends FrameLayout implements Checkable {    private boolean isChecked;    private static final int[] CHECK_STATE = new int[]{android.R.attr.state_checked};    public TagView(Context context) {        super(context);    }    public View getTagView() {        return getChildAt(0);    }    @Override    public int[] onCreateDrawableState(int extraSpace) {        int[] states = super.onCreateDrawableState(extraSpace + 1);        if (isChecked()) {            mergeDrawableStates(states, CHECK_STATE);        }        return states;    }    /**     * Change the checked state of the view     *     * @param checked The new checked state     */    @Override    public void setChecked(boolean checked) {        if (this.isChecked != checked) {            this.isChecked = checked;            refreshDrawableState();        }    }    /**     * @return The current checked state of the view     */    @Override    public boolean isChecked() {        return isChecked;    }    /**     * Change the checked state of the view to the inverse of its current state     */    @Override    public void toggle() {        setChecked(!isChecked);    }}




TagAdapter适配器

import android.view.View;import com.bwei.lgank.myview.FlowLayout;import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.List;import java.util.Set;public abstract class TagAdapter<T> {    private List<T> mTagDatas;    private OnDataChangedListener mOnDataChangedListener;    private HashSet<Integer> mCheckedPosList = new HashSet<Integer>();    public TagAdapter(List<T> datas) {        mTagDatas = datas;    }    public TagAdapter(T[] datas) {        mTagDatas = new ArrayList<T>(Arrays.asList(datas));    }    public interface OnDataChangedListener {        void onChanged();    }    public void setOnDataChangedListener(OnDataChangedListener listener) {        mOnDataChangedListener = listener;    }    public void setSelectedList(int... poses) {        Set<Integer> set = new HashSet<>();        for (int pos : poses) {            set.add(pos);        }        setSelectedList(set);    }    public void setSelectedList(Set<Integer> set) {        mCheckedPosList.clear();        if (set != null)            mCheckedPosList.addAll(set);        notifyDataChanged();    }    public HashSet<Integer> getPreCheckedList() {        return mCheckedPosList;    }    public int getCount() {        return mTagDatas == null ? 0 : mTagDatas.size();    }    public void notifyDataChanged() {        mOnDataChangedListener.onChanged();    }    public T getItem(int position) {        return mTagDatas.get(position);    }    public abstract View getView(FlowLayout parent, int position, T t);    public boolean setSelected(int position, T t) {        return false;    }}


原创粉丝点击