网友真实露脸自拍10p,成人国产精品秘?久久久按摩,国产精品久久久久久无码不卡,成人免费区一区二区三区

小程序模板網(wǎng)

微信小程序開(kāi)發(fā)之帶搜索記錄的搜索框

發(fā)布時(shí)間:2017-12-29 18:14 所屬欄目:小程序開(kāi)發(fā)教程

http://blog.csdn.net/carson_ho/article/details/53366570

 

 

前言

  • 像下圖的搜索功能在Android開(kāi)發(fā)中非常常見(jiàn)

 

搜索功能

  • 今天我將手把手教大家如何實(shí)現(xiàn)具備歷史搜索記錄的搜索框

目錄

目錄


1. 使用場(chǎng)景

在敲下代碼前,理解用戶的功能使用場(chǎng)景是非常重要的,這樣有助于我們更好地去進(jìn)行功能的實(shí)現(xiàn),使用場(chǎng)景如下:

  • 用戶需要進(jìn)行某類事物的搜索(通過(guò)文字輸入進(jìn)行精確搜索)
  • 在搜索框輸入時(shí),通過(guò)顯示搜索歷史從而降低用戶二次搜索的成本

簡(jiǎn)單來(lái)說(shuō),就是輸入過(guò)字段會(huì)保存,當(dāng)用戶再次搜索該字段時(shí),能快速幫助用戶輸入


2. 功能業(yè)務(wù)流程

搜索功能場(chǎng)景


3. 明確功能點(diǎn)

  • 功能1:關(guān)鍵字搜索
  • 功能2:實(shí)時(shí)顯示歷史搜索記錄
  • 功能3:歷史搜索記錄保存
  • 功能4:將軟鍵盤(pán)上的”回車按鈕“改為”搜索按鈕“

4. 涉及到的知識(shí)點(diǎn)

知識(shí)點(diǎn)

4.1 SQLite數(shù)據(jù)庫(kù)的增刪改查操作

  • 在數(shù)據(jù)庫(kù)建立一個(gè)叫records的表用于存儲(chǔ)搜索歷史記錄 
     里面只有一列name來(lái)存儲(chǔ)歷史記錄
        db.execSQL("create table records(id integer primary key autoincrement,name varchar(200))");
  • 通過(guò)插入和刪除操作數(shù)據(jù)庫(kù)里面的數(shù)據(jù)
  • 通過(guò)查詢操作來(lái)顯示數(shù)據(jù)庫(kù)里面的數(shù)據(jù)到ListView上 

    已搜索的關(guān)鍵字再次搜索不重復(fù)添加到數(shù)據(jù)庫(kù)

注:對(duì)于SQLlite數(shù)據(jù)庫(kù)的操作詳情請(qǐng)看我寫(xiě)的文章:Android:SQLlite數(shù)據(jù)庫(kù)操作最詳細(xì)解析

4.2 ListView和ScrollView的嵌套沖突

  • 問(wèn)題:ListView和ScrollView一起使用會(huì)有沖突,導(dǎo)致ListView顯示不全
  • 解決方案:本人采用繼承ListView并重寫(xiě)它的onMeasure()方法來(lái)解決沖突。

    1. 至于兩者的滑動(dòng)沖突則暫時(shí)不需要處理(默認(rèn)拉動(dòng)ScrollView),這樣用戶就會(huì)感覺(jué)里面的搜索歷史項(xiàng)和清空搜索記錄項(xiàng)是在ListView里面一樣,符合設(shè)計(jì)。
    2. 更多解決方法請(qǐng)看:ListView和ScrollView的嵌套沖突解決方案
  • 具體代碼如下:

//解決ListView和ScrollView的沖突
public class Search_Listview extends ListView {
    public Search_Listview(Context context) {
        super(context);
    }

    //通過(guò)復(fù)寫(xiě)其onMeasure方法、達(dá)到對(duì)ScrollView適配的效果
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

Search_View.java

  • 作用:用于封裝搜索框功能的所有操作(涵蓋歷史搜索記錄的插入、刪除、查詢和顯示)
  • 具體代碼如下:
package scut.carson_ho.search_layout;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by Carson_Ho on 16/11/15.
 */
public class Search_View extends LinearLayout {

    private Context context;

    /*UI組件*/
    private TextView tv_clear;
    private EditText et_search;
    private TextView tv_tip;
    private ImageView iv_search;

    /*列表及其適配器*/
    private Search_Listview listView;
    private BaseAdapter adapter;

    /*數(shù)據(jù)庫(kù)變量*/
    private RecordSQLiteOpenHelper helper ;
    private SQLiteDatabase db;


    /*三個(gè)構(gòu)造函數(shù)*/
    //在構(gòu)造函數(shù)里直接對(duì)搜索框進(jìn)行初始化 - init()
    public Search_View(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public Search_View(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public Search_View(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }


    /*初始化搜索框*/
    private void init(){

        //初始化UI組件
        initView();


        //實(shí)例化數(shù)據(jù)庫(kù)SQLiteOpenHelper子類對(duì)象
        helper = new RecordSQLiteOpenHelper(context);

        // 第一次進(jìn)入時(shí)查詢所有的歷史記錄
        queryData("");

        //"清空搜索歷史"按鈕
        tv_clear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //清空數(shù)據(jù)庫(kù)
                deleteData();
                queryData("");
            }
        });

        //搜索框的文本變化實(shí)時(shí)監(jiān)聽(tīng)
        et_search.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) {

            }

            //輸入后調(diào)用該方法
            @Override
            public void afterTextChanged(Editable s) {

                if (s.toString().trim().length() == 0) {
                    //若搜索框?yàn)榭?則模糊搜索空字符,即顯示所有的搜索歷史
                    tv_tip.setText("搜索歷史");
                } else {
                    tv_tip.setText("搜索結(jié)果");
                }

                //每次輸入后都查詢數(shù)據(jù)庫(kù)并顯示
                //根據(jù)輸入的值去模糊查詢數(shù)據(jù)庫(kù)中有沒(méi)有數(shù)據(jù)
                String tempName = et_search.getText().toString();
                queryData(tempName);

            }
        });


        // 搜索框的鍵盤(pán)搜索鍵
        // 點(diǎn)擊回調(diào)
        et_search.setOnKeyListener(new View.OnKeyListener() {// 輸入完后按鍵盤(pán)上的搜索鍵


            // 修改回車鍵功能
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
                    // 隱藏鍵盤(pán),這里getCurrentFocus()需要傳入Activity對(duì)象,如果實(shí)際不需要的話就不用隱藏鍵盤(pán)了,免得傳入Activity對(duì)象,這里就先不實(shí)現(xiàn)了
//                    ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
//                            getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

                    // 按完搜索鍵后將當(dāng)前查詢的關(guān)鍵字保存起來(lái),如果該關(guān)鍵字已經(jīng)存在就不執(zhí)行保存
                    boolean hasData = hasData(et_search.getText().toString().trim());
                    if (!hasData) {
                        insertData(et_search.getText().toString().trim());

                        queryData("");
                    }
                    //根據(jù)輸入的內(nèi)容模糊查詢商品,并跳轉(zhuǎn)到另一個(gè)界面,這個(gè)需要根據(jù)需求實(shí)現(xiàn)
                    Toast.makeText(context, "點(diǎn)擊搜索", Toast.LENGTH_SHORT).show();

                }
                return false;
            }
        });



        //列表監(jiān)聽(tīng)
        //即當(dāng)用戶點(diǎn)擊搜索歷史里的字段后,會(huì)直接將結(jié)果當(dāng)作搜索字段進(jìn)行搜索
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                //獲取到用戶點(diǎn)擊列表里的文字,并自動(dòng)填充到搜索框內(nèi)
                TextView textView = (TextView) view.findViewById(android.R.id.text1);
                String name = textView.getText().toString();
                et_search.setText(name);
                Toast.makeText(context, name, Toast.LENGTH_SHORT).show();

            }
        });


        //點(diǎn)擊搜索按鈕后的事件
        iv_search.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean hasData = hasData(et_search.getText().toString().trim());
                if (!hasData) {
                    insertData(et_search.getText().toString().trim());

                    //搜索后顯示數(shù)據(jù)庫(kù)里所有搜索歷史是為了測(cè)試
                    queryData("");
                }
                //根據(jù)輸入的內(nèi)容模糊查詢商品,并跳轉(zhuǎn)到另一個(gè)界面,這個(gè)根據(jù)需求實(shí)現(xiàn)
                Toast.makeText(context, "clicked!", Toast.LENGTH_SHORT).show();
            }
        });




    }





    /**
     * 封裝的函數(shù)
     */

    /*初始化組件*/
    private void initView(){
        LayoutInflater.from(context).inflate(R.layout.search_layout,this);
        et_search = (EditText) findViewById(R.id.et_search);
        tv_clear = (TextView) findViewById(R.id.tv_clear);
        tv_tip = (TextView) findViewById(R.id.tv_tip);
        listView = (Search_Listview) findViewById(R.id.listView);
        iv_search = (ImageView) findViewById(R.id.iv_search);
    }

    /*插入數(shù)據(jù)*/
    private void insertData(String tempName) {
        db = helper.getWritableDatabase();
        db.execSQL("insert into records(name) values('" + tempName + "')");
        db.close();
    }

    /*模糊查詢數(shù)據(jù) 并顯示在ListView列表上*/
    private void queryData(String tempName) {

        //模糊搜索
        Cursor cursor = helper.getReadableDatabase().rawQuery(
                "select id as _id,name from records where name like '%" + tempName + "%' order by id desc ", null);
        // 創(chuàng)建adapter適配器對(duì)象,裝入模糊搜索的結(jié)果
        adapter = new SimpleCursorAdapter(context, android.R.layout.simple_list_item_1, cursor, new String[] { "name" },
                new int[] { android.R.id.text1 }, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
        // 設(shè)置適配器
        listView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }

    /*檢查數(shù)據(jù)庫(kù)中是否已經(jīng)有該條記錄*/
    private boolean hasData(String tempName) {
        //從Record這個(gè)表里找到name=tempName的id
        Cursor cursor = helper.getReadableDatabase().rawQuery(
                "select id as _id,name from records where name =?", new String[]{tempName});
        //判斷是否有下一個(gè)
        return cursor.moveToNext();
    }

    /*清空數(shù)據(jù)*/
    private void deleteData() {
        db = helper.getWritableDatabase();
        db.execSQL("delete from records");
        db.close();
    }
}

search_layout.xml

  • 作用:搜索框的布局
  • 具體代碼如下:
<?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="match_parent"
    android:focusableInTouchMode="true"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:background="#E54141"
        android:orientation="horizontal"
        android:paddingRight="16dp">

        <ImageView
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_gravity="center_vertical"
            android:padding="10dp"
            android:src="@drawable/back" />

        <EditText
            android:id="@+id/et_search"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="264"
            android:background="@null"
            android:drawablePadding="8dp"
            android:gravity="start|center_vertical"
            android:hint="輸入查詢的關(guān)鍵字"
            android:imeOptions="actionSearch"
            android:singleLine="true"
            android:textColor="@android:color/white"
            android:textSize="16sp" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/search"
            android:layout_gravity="center_vertical"
            android:id="@+id/iv_search"/>

    </LinearLayout>


    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingLeft="20dp"
                >

                <TextView
                    android:id="@+id/tv_tip"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:gravity="left|center_vertical"
                    android:text="搜索歷史" />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#EEEEEE"/>

                <scut.carson_ho.search_layout.Search_Listview
                    android:id="@+id/listView"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                </scut.carson_ho.search_layout.Search_Listview>


            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#EEEEEE"/>

            <TextView
                android:id="@+id/tv_clear"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:background="#F6F6F6"
                android:gravity="center"
                android:text="清除搜索歷史" />

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginBottom="20dp"
                android:background="#EEEEEE"/>
        </LinearLayout>

    </ScrollView>
</LinearLayout>

5.3 測(cè)試結(jié)果

測(cè)試結(jié)果

5.4 Demo地址

Carson的Github地址:Search_Layout_Demo


6. 總結(jié)

  • 通過(guò)閱讀本文,你已經(jīng)全面了解Android中如何實(shí)現(xiàn)具備歷史搜索記錄的搜索框
  • 接下來(lái)會(huì)介紹繼續(xù)介紹Android開(kāi)發(fā)中的常用知識(shí),有興趣可以繼續(xù)關(guān)注Carson_Ho的安卓開(kāi)發(fā)筆記


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開(kāi)源 碼云倉(cāng)庫(kù):starfork
本文地址:http://www.xiuhaier.com/wxmini/doc/course/18312.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢:800182392 點(diǎn)擊咨詢
QQ在線咨詢
AI智能客服 ×