有历史记录的搜索框(带数据库)

1.MyOpenHelper (数据库)
public class MyOpenHelper extends SQLiteOpenHelper{
    public MyOpenHelper(Context context) {
        super(context, "demo.db", null, 1);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建数据库的时候,创建表格
        db.execSQL("create table history(_id INTEGER primary key autoincrement,content varchar(20))");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}
2.MySearchView (搜索框)
public class MySearchView extends LinearLayout{
    private EditText et_search;
    public MySearchView(Context context) {
        this(context,null);
    }
    public MySearchView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }
    public MySearchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        View view = View.inflate(context, R.layout.searchview_layout, this);
        et_search = (EditText)view.findViewById(R.id.et_search);
    }
    //获取信息
    public String getContent(){
        return et_search.getText().toString();
    }
}
2.5  searchview_layout(搜索框对应的布局)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@drawable/seach_bg"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:padding="6px">
        <ImageView
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src="@drawable/a_4"/>
        <EditText
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:id="@+id/et_search"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:background="@null"
            android:hint="请输入要搜索的关键词"
            android:textColor="#333"
            android:textColorHint="#666"
            android:textSize="12sp" />

    </LinearLayout>
</LinearLayout>

3.MyFlowLayout (流式布局)
public class MyFlowLayout extends ViewGroup{
    private int useWidth;
    private int MaxHeight;
    private int HorizonytalSpace = 5;
    private int VerticalSpaace = 5;
    private Line mLine;
    private int MaxLine = 100;
    private ArrayList<Line> LineList = new ArrayList<Line>();
//    private  int
    public MyFlowLayout(Context context) {
        super(context);
    }
    public MyFlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //获取控件的具体尺寸
        int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();//获取空间的宽度
        int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();//获取控件的高度
        //获取控件的测量模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);//宽度的测量模式
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);//高度的测量模式
        //开始遍历所有的子控件
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            //获取子控件的尺寸,与测量模式
            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,widthMode == MeasureSpec.EXACTLY?MeasureSpec.AT_MOST:widthMode);
            int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height,heightMode == MeasureSpec.EXACTLY?MeasureSpec.AT_MOST:heightMode);
            //测量子控件
            childView.measure(childWidthMeasureSpec,childHeightMeasureSpec);
            int childWidth = childView.getMeasuredWidth();//子控件的宽度
            int childHeight = childView.getMeasuredHeight();//子控件的高度
            useWidth += childWidth;
            if(mLine == null){
                mLine = new Line();
            }
            if(useWidth < width){
                //未超过最大限度,可以添加到当前行
                mLine.addView(childView);
                useWidth += HorizonytalSpace;
                if(useWidth >= width){
                    if(!newLine()){
                        break;//创建失败,结束for循环
                    }
                }
            }else {
                //2.但前行没有控件,必须加入到当前行,然后换行
                if(mLine.getLineCount() == 0){
                    //添加到当前行,然后换行
                    mLine.addView(childView);
                    LineList.add(mLine);
                    if(!newLine()){
                        break;
                    }
                }else {
                    //超过最大高度,
                    //1.当前行有控件,需要新建一行
                    if(!newLine()){
                        break;
                    }
                    mLine.addView(childView);
                    useWidth += HorizonytalSpace + childWidth;
                }
            }
            if (mLine != null && mLine.getLineCount() > 0
                    && !LineList.contains(mLine)) {
                // 由于前面采用判断长度是否超过最大宽度来决定是否换行,则最后一行可能因为还没达到最大宽度,所以需要验证后加入集合中
                LineList.add(mLine);
            }
        }
        //为控件设置宽度,高度
        int Totalwidth = MeasureSpec.getSize(widthMeasureSpec);
        int TotalHeight = 0;
        for (int i = 0; i <LineList.size() ; i++) {
            TotalHeight += LineList.get(i).MaxHeight;
        }
        TotalHeight += (LineList.size() - 1)*VerticalSpaace + getPaddingTop() + getPaddingBottom();
        setMeasuredDimension(Totalwidth,TotalHeight);
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //遍历行集合(LineList),
        int Top = getPaddingTop();
        int Left = getPaddingLeft();
        for (int i = 0; i < LineList.size(); i++) {
            Line line = LineList.get(i);
            line.layoutView(Left,Top);
            Top += line.MaxHeight + VerticalSpaace;
        }
    }
    private boolean newLine(){
        //判断是否超过最大行数
        if(LineList.size() < MaxLine){
            //将上一行添加到,LineList中
            LineList.add(mLine);
            mLine = new Line();//创建一个新的行
            //新的一行,使用的数据为0
            useWidth = 0;
            MaxHeight = 0;
            return true;//创建成功返回true
        }
        return false;
    }
    //创建一个类,用来处理每一行的数据
    class Line{
        private int mLineWidth = 0;
        private int MaxHeight = 0;
        private ArrayList<View> viewlist = new ArrayList<View>();
        public void addView(View view){
            viewlist.add(view);
            mLineWidth += view.getMeasuredWidth();
            int childHeight = view.getMeasuredHeight();
            MaxHeight = MaxHeight < childHeight?childHeight:MaxHeight;
        }
        public int getLineCount(){
            return viewlist.size();
        }
        public void layoutView(int l,int t){
            //对此行的数据进行布局
            int Left = l;
            int Top = t;
            int childCount = viewlist.size();
            int width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() -(childCount-1) * HorizonytalSpace;
            //计算剩余宽度
            int surplusWidth  = width - mLineWidth;
            if(surplusWidth > 0){
                //计算每个布局的添加量
                int widthOffSet = (int) (surplusWidth * 1.0f/viewlist.size() + 0.5f);
                for (int i = 0; i < viewlist.size(); i++) {
                    View view = viewlist.get(i);
                    int childWidth = view.getMeasuredWidth();
                    int childHeight = view.getMeasuredHeight();
                    childWidth += widthOffSet;//重新分配控件的高度
                    int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth,MeasureSpec.EXACTLY);
                    int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight,MeasureSpec.EXACTLY);
                    view.measure(childWidthMeasureSpec,childHeightMeasureSpec);
                    //分配布局控件时的偏移量
                    int TopOffSet = (MaxHeight - childHeight) / 2;
                    TopOffSet = TopOffSet>0?TopOffSet:0;//如果TopOffSet(竖直方向的偏移量)小于0,则设置为0;
                    view.layout(Left,Top+ TopOffSet,Left +childWidth,Top + TopOffSet + childHeight);
                    Left += HorizonytalSpace + childWidth;
                }
            }else{
            }
        }
    }
    public void setHorizontalSpacing(int horizonytalSpace) {
        HorizonytalSpace = horizonytalSpace;
    }
    public void setVerticalSpacing(int verticalSpaace) {
        VerticalSpaace = verticalSpaace;
    }
}
4.MainActivity (主方法)
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private MyOpenHelper myOpenHelper;
    private MySearchView mySearchView;
    private MyFlowLayout myFlowLayout;
    private MyListView myListView;
    private TextView sousuo;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化页面
        initViews();
        //初始化数据库
        initDatabase();
    }
    private void initDatabase() {
        myOpenHelper = new MyOpenHelper(this);
        SQLiteDatabase database = myOpenHelper.getReadableDatabase();
    }
    private void initViews() {
        mySearchView = (MySearchView)findViewById(R.id.mySearchView);
        myFlowLayout = (MyFlowLayout)findViewById(R.id.flow_hot_search);
        myListView = (MyListView)findViewById(R.id.lv_search);
        sousuo = (TextView)findViewById(R.id.sousuo);
        sousuo.setOnClickListener(this);
        ImageView dele = (ImageView) findViewById(R.id.iv_delete);
        dele.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.sousuo:
                //获取数据
                String con = mySearchView.getContent();
                //存入数据库
                SQLiteDatabase db = myOpenHelper.getReadableDatabase();
                ContentValues contentValues = new ContentValues();
                contentValues.put("content", con);
                db.insert("history", null, contentValues);
                db.close();
                //展示在列表
//                查询数据
                SQLiteDatabase db1 = myOpenHelper.getReadableDatabase();
                Cursor cursor = db1.query("history", null, null, null, null, null, null);
                List<String> list = new ArrayList<>();
                while (cursor.moveToNext()) {
                    String content = cursor.getString(cursor.getColumnIndex("content"));
                    list.add(content);
                }
                db1.close();
                //设置适配器
                MyAdapter myAdapter = new MyAdapter(MainActivity.this, list);
                myListView.setAdapter(myAdapter);
                break;
            case R.id.iv_delete:
                SQLiteDatabase db2 = myOpenHelper.getReadableDatabase();
                db2.delete("history",null,null);
                db2.close();

                SQLiteDatabase db3 = myOpenHelper.getReadableDatabase();
                Cursor cursor3 = db3.query("history", null, null, null, null, null, null);
                List<String> list1 = new ArrayList<>();
                while (cursor3.moveToNext()) {
                    String content = cursor3.getString(cursor3.getColumnIndex("content"));
                    list1.add(content);
                }
                db3.close();
                //设置适配器
                MyAdapter myAdapter2 = new MyAdapter(MainActivity.this, list1);
                myListView.setAdapter(myAdapter2);
                break;
        }
    }
}
4.5  activity_main(主布局)
<ScrollView
    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="match_parent" tools:context="com.example.myzhoukao1_shizuo.MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <com.example.myzhoukao1_shizuo.MySearchView
                android:id="@+id/mySearchView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"></com.example.myzhoukao1_shizuo.MySearchView>
            <TextView
                android:id="@+id/sousuo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="搜索"
                android:textSize="20sp" />
        </LinearLayout>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="20px"
            android:text="热门搜索"
            android:textSize="36px" />
        <com.example.myzhoukao1_shizuo.MyFlowLayout
            android:id="@+id/flow_hot_search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#F00"
                android:text="电饭煲" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="#F00"
                android:text="手机" />

        </com.example.myzhoukao1_shizuo.MyFlowLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="20px">
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="历史搜索"
                android:textSize="36px" />
            <ImageView
                android:id="@+id/iv_delete"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@drawable/cha" />
        </LinearLayout>
        <com.example.myzhoukao1_shizuo.MyListView
            android:id="@+id/lv_search"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </com.example.myzhoukao1_shizuo.MyListView>
    </LinearLayout>
</ScrollView>
5.MyAdapter (适配器)
public class MyAdapter extends BaseAdapter{
    private final Context context;
    private final List<String> list;
    public MyAdapter(Context context, List<String> list) {
        this.context = context;
        this.list = list;
    }
    @Override
    public int getCount() {
        return list.size();
    }
    @Override
    public Object getItem(int position) {
        return null;
    }
    @Override
    public long getItemId(int position) {
        return 0;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView textView = new TextView(context);
        textView.setText(list.get(position));
        textView.setTextSize(20);
        return textView;
    }
}
6.MyListView (防止历史记录只显示一行)
public class MyListView extends ListView{
    public MyListView(Context context) {
        super(context);
    }
    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMea = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMea);
    }
}
7.seach_bg(搜索框背景布局一般写在drawable里)
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size
        android:width="100dp"
        android:height="30dp" />
    <corners android:radius="15dp" />
    <solid android:color="@color/colorTextGroupBg"/>
</shape>
8.效果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值