自定义View 流式布局(历史搜索,热门搜索)

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:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".activity.SearchActivity"
    android:orientation="vertical"
    >
    <bawei.com.week2.customview.HeadView
        android:id="@+id/head_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></bawei.com.week2.customview.HeadView>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <bawei.com.week2.customview.TitleView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:layout_marginLeft="30dp"
            app:textColor="@color/colorBlack"
            android:text="搜索历史"
            android:textSize="25sp"
            />
        <ImageView
            android:id="@+id/image_del"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/del"
            android:layout_alignParentRight="true"
            android:layout_marginTop="30dp"
            />
    </RelativeLayout>
    <bawei.com.week2.customview.CustonFlowView
        android:id="@+id/flow_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="30dp"
        ></bawei.com.week2.customview.CustonFlowView>
    <bawei.com.week2.customview.TitleView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="30dp"
        app:textColor="@color/colorRed"
        android:text="热门搜索"
        android:textSize="25sp"
        />
    <bawei.com.week2.customview.CustonFlowView
        android:id="@+id/hot_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="30dp"
        ></bawei.com.week2.customview.CustonFlowView>


</LinearLayout>

HeadView的布局(headitem)

<?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="horizontal"
    >
   <ImageView
       android:id="@+id/imageview"
       android:layout_width="30dp"
       android:layout_height="30dp"
       android:background="@drawable/search"
       android:layout_marginLeft="10dp"
       android:layout_marginTop="15dp"
       />
    <EditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="10dp"
        android:ems="20"
        android:hint="请输入想要输入的内容"
        />

</LinearLayout>

HeadView代码

public class HeadView extends LinearLayout {
    private Context mContext;
    private ImageView imageView;
    private EditText editText;

    public HeadView(Context context) {
        super(context);
        mContext=context;
        initView();
    }

    public HeadView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext=context;
        initView();
    }

    public void initView(){
        //添加布局
        View view=View.inflate(mContext,R.layout.headitem,null);
        //获取资源ID
        imageView = view.findViewById(R.id.imageview);
        editText = view.findViewById(R.id.edit_text);
        imageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //6.在将要判断的地方,判断是否为空
                if(mCallBack!=null){
                    //7.执行回调方法,传入参数
                    mCallBack.getData(editText.getText().toString());
                }
            }
        });
        addView(view);
    }
    //3.定义成员变量
    CallBack mCallBack;
    //4.传入,并且给成员变量赋值
    //5.在想要的地方进行回调
    public void setOnCallBack(CallBack callBack){
        mCallBack=callBack;
    }
    //1.定义接口
    public interface CallBack{
        //2.定义方法,传入参数
        void getData(String edit);
    }
}

自定义属性在values下建一个attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TitleView">
        <attr name="textColor" format="color"></attr>
    </declare-styleable>
</resources>

TitleView代码(自定义属性)

@SuppressLint("AppCompatCustomView")
public class TitleView extends TextView {

    public TitleView(Context context) {
        super(context);
    }

    public TitleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleView);
        int color = typedArray.getColor(R.styleable.TitleView_textColor, Color.BLACK);
        setTextColor(color);
        //属性回收
        typedArray.recycle();

    }
}

CustonFlowView中的代码

public class CustonFlowView extends LinearLayout {
    private int mChildHeight;//最高的孩子
    private int mLeft=20;//左边距
    private int mTop=20; //上边距
    public CustonFlowView(Context context) {
        super(context);
    }

    public CustonFlowView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //定义父窗口的宽高
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        //测量孩子的大小
        measureChildren(widthMeasureSpec,heightMeasureSpec);
        //找到最高的孩子
        findMaxHeight();
        //初始化
        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())>widthSize){
                   top+=mChildHeight+mTop;
                   left=0;
               }
            }
            left+=view.getMeasuredWidth()+mLeft;
        }
        setMeasuredDimension(widthSize,(top+mChildHeight)>heightSize?heightSize:top+mChildHeight);


    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        findMaxHeight();
        //初始化
        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+=mChildHeight+mTop;
                    left=0;
                }
            }
            view.layout(left,top,view.getMeasuredWidth()+left,top+mChildHeight);
            left+=view.getMeasuredWidth()+mLeft;
        }

    }

    private void findMaxHeight() {
        mChildHeight=0;
        int childCount = getChildCount();
        for(int i=0;i<childCount;i++){
            View view = getChildAt(i);
            if(view.getMeasuredHeight()>mChildHeight){
                mChildHeight=view.getMeasuredHeight();
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
}

数据库
SqlieHelper

public class SqliteHelper extends SQLiteOpenHelper {
    public SqliteHelper(@Nullable Context context) {
        super(context, "Search.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table search(id integer primary key autoincrement," +
                "name text," +
                "mTag text)");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

数据库中查询用到的bean类

public class NameBean {
    public String name;
    public String mTag;

    public NameBean(String name, String mTag) {
        this.name = name;
        this.mTag = mTag;
    }

    public String getName() {
        return name;
    }

    public String getmTag() {
        return mTag;
    }
}

Dao层

public class Dao {
    private SqliteHelper helper;
    private SQLiteDatabase database;
    public Dao(Context context){
        helper=new SqliteHelper(context);
        database=helper.getReadableDatabase();
    }
    //添加
    public void add(String name,String mTag){
        ContentValues values=new ContentValues();
        values.put("name",name);
        values.put("mTag",mTag);
        database.insert("search",null,values);
    }
    //查询
    public List<NameBean> select(){
        List<NameBean> list=new ArrayList<>();
        Cursor query = database.query("search", null, null, null, null, null, null);
        while (query.moveToNext()){
            String name = query.getString(query.getColumnIndex("name"));
            String mTag = query.getString(query.getColumnIndex("mTag"));
            NameBean bean=new NameBean(name,mTag);
            list.add(bean);

        }
        return list;
    }
    //删除
    public void delAll(){
        database.delete("search",null,null);
    }
    public void del(String tj){
        database.delete("search","mTag=?",new String[]{tj});
    }

}

Activity中的代码

public class SearchActivity extends AppCompatActivity {

    private HeadView headView;
    private CustonFlowView custonFlowView;
    private CustonFlowView hot_view;
    private String str[]=new String[]{"辣条","薯片","火腿肠","酸辣粉","米线","奶茶嫁给粉","麻辣烫","黄焖鸡","大虾","酸菜鱼"};
    private Dao dao;
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        initView(savedInstanceState);
        initData();
    }

   private void initData() {
        dao=new Dao(this);
        //查询
       final List<NameBean> list = dao.select();
       for(int i=0;i<list.size();i++){
           TextView textView=new TextView(SearchActivity.this);
           textView.setText(list.get(i).getName());
           textView.setTextSize(20);
           textView.setTextColor(Color.BLACK);
           textView.setPadding(10,10,10,10);
           textView.setBackgroundResource(R.drawable.shape_text);
           custonFlowView.addView(textView);
           //删除
           final int index=i;
           textView.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   dao.del(list.get(index).getmTag());
                   custonFlowView.removeView(v);
               }
           });
       }

       headView.setOnCallBack(new HeadView.CallBack() {
            @Override
            public void getData(String edit) {
                String uuid = UUID.randomUUID().toString();

                final TextView textView=new TextView(SearchActivity.this);
                textView.setTag(uuid);
                textView.setText(edit);
                textView.setTextSize(20);
                textView.setTextColor(Color.BLACK);
                textView.setPadding(10,10,10,10);
                textView.setBackgroundResource(R.drawable.shape_text);
                dao.add(edit,uuid);
                custonFlowView.addView(textView);
                //删除
                textView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dao.del(v.getTag().toString());
                        custonFlowView.removeView(v);
                    }
                });


            }
        });
    //全部删除
       imageView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               dao.delAll();
               custonFlowView.removeAllViews();
           }
       });

       //热门搜索
        for (int i=0;i<str.length;i++){
            TextView textView=new TextView(SearchActivity.this);
            textView.setText(str[i]);
            textView.setTextSize(20);
            textView.setTextColor(Color.BLACK);
            textView.setPadding(10,10,10,10);
            textView.setBackgroundResource(R.drawable.shape_text);
            hot_view.addView(textView);
        }

    }

    private void initView(Bundle savedInstanceState) {
        headView = findViewById(R.id.head_view);
        custonFlowView = findViewById(R.id.flow_view);
        hot_view = findViewById(R.id.hot_view);
        imageView = findViewById(R.id.image_del);

    }
}

shape

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
    android:radius="20dp"
    ></corners>
    <stroke
        android:width="1dp"
        android:color="@color/colorPrimary"
        ></stroke>

</shape>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值