Android之搜索功能的实现

效果图展示:
Android之搜索功能的实现_第1张图片
实现的效果:
1.热门商品搜索栏中的数据从网络接口获取
2.搜索历史商品中的数据从SQLite数据库中获取
3.当点击热门商品搜索的时候,该数据会立刻出现在搜索历史商品中,不会重复增加已经出现过的商品,历史中的商品按照最新时间排序。
4.效果图中的button没有做监听,其实现原理是:获取EditText中的内容,按照服务端的接口格式要求,发送get请求,访问服务端获取相应的数据。
5.搜索历史商品栏的展示数据比较长是由于在bean中对toString 方法做了以下的重写。直接return hotword 也是可以的。

@Override
    public String toString() {
        return "SearchDBData [hotword=" + hotword + "]";
    }

重要知识点:
1.AsyncTask 的使用:
2.json数据解析:
3.ExpandableListView的使用:
4.表的设计和SQLiteDatabase的增删查改操作:

先贴上代码,后面再对一些重要的代码做解释说明:

public class SearchFragment extends BaseFragment {

    private ExpandableListView mExpandableListView;
    private EditText inputEditText;
    private Button searchButton;
    private SearchRecommendData recommendData;
    private ArrayList keywordsList = new ArrayList();
    private MyAdapter adapter;

    private List findAllList = new ArrayList();
    private HistoryDao dao;

    @Override
    public void getData() {
        // 访问网络获取数据:热门搜索
        new AsyncTask() {

            @Override
            protected Void doInBackground(Void... params) {
                String url = "http://xxxxxxxxxxxxxxx";
                String json = HttpUtil.get(url, "utf-8");
                // recommendData = JSON.parseObject(json,
                // SearchRecommendData.class);
                Gson gson = new Gson();
                recommendData = gson.fromJson(json, SearchRecommendData.class);
                keywordsList = recommendData.search_keywords;

                // 访问数据库获取历史记录
                findAllList = dao.findAll();

                return null;
            };

            protected void onPostExecute(Void result) {
                if (adapter == null) {
                    adapter = new MyAdapter();
                    mExpandableListView.setAdapter(adapter);
                } else {
                    adapter.notifyDataSetChanged();
                }
            };

        }.execute();

    }

    @Override
    public int getLayoutId() {

        return R.layout.fragment_search;
    }

    @Override
    public void initView() {

        dao = new HistoryDao(mContext);
        // 查找fragment中控件
        mExpandableListView = (ExpandableListView) rootView
                .findViewById(R.id.elv_search);
        inputEditText = (EditText) rootView
                .findViewById(R.id.et_input_searchfragment);
        searchButton = (Button) rootView.findViewById(R.id.btn_searchfragment);

        mExpandableListView.setGroupIndicator(null);

        // 对mExpandableListView设置监听事件:
        MyonChildClickListener childListener = new MyonChildClickListener();
        mExpandableListView.setOnChildClickListener(childListener);

    }

    private class MyonChildClickListener implements OnChildClickListener {

        @Override
        public boolean onChildClick(ExpandableListView parent, View v,
                int groupPosition, int childPosition, long id) {

            // Toast.makeText(mContext, keywordsList.get(childPosition),
            // 0).show();
            // String inputStr = inputEditText.getText().toString();

            String hotword = keywordsList.get(childPosition);
            // ContentValues values = new ContentValues();
            // values.put("hotword", hotword);
            // values.put("updatetime",System.currentTimeMillis());
            // dao.add(values);
            dao.addOrUpdate(hotword);
            findAllList.clear();
            findAllList = dao.findAll();
            adapter.notifyDataSetChanged();
            return true;// 自己处理事情
        }

    }

    private class MyAdapter extends BaseExpandableListAdapter {

        @Override
        public int getGroupCount() {
            if (findAllList != null) {
                return 2;
            } else {
                return 1;
            }

        }

        @Override
        public int getChildrenCount(int groupPosition) {
            // 返回单一组中的数量
            if (findAllList != null) {
                if (groupPosition == 0) {
                    return keywordsList.size();
                } else if (groupPosition == 1) {
                    return findAllList.size();
                }
            }

            return keywordsList.size();

        }

        @Override
        public Object getGroup(int groupPosition) {
            if (groupPosition == 0) {
                return "热门商品搜索";// 初始化组件的时候用到:
            } else if (groupPosition == 1) {
                return "搜索历史商品";
            }
            return null;
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            if (findAllList != null) {
                if (groupPosition == 0) {
                    return keywordsList.get(childPosition);
                } else if (groupPosition == 1) {
                    return findAllList.get(childPosition).toString();
                }
            }

            return keywordsList.get(childPosition);

        }

        @Override
        public long getGroupId(int groupPosition) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public boolean hasStableIds() {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded,
                View convertView, ViewGroup parent) {
            View view = View.inflate(mContext, R.layout.search_group, null);
            TextView groupnameTextView = (TextView) view
                    .findViewById(R.id.tv_name_search);
            String name = (String) getGroup(groupPosition);
            groupnameTextView.setText(name);
            return view;

        }

        @Override
        public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent) {
            String items = (String) getChild(groupPosition, childPosition);
            View view = View.inflate(mContext, R.layout.search_child, null);
            TextView childnameTextView = (TextView) view
                    .findViewById(R.id.tv_childname_search);
            childnameTextView.setText(items);
            return view;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            // true:支持点击事件
            return true;
        }

    }
}

先说AsyncTask,由于个人习惯性将获取数据的来源和展示数据写在同一个activity或是fragment中,哪些数据有用,就将哪些数据设置为成员变量,不需要再传递数据了,这是写在同一个类中的好处。
所以在用AsyncTask的时候可以看到传递的参数都是Void的。如果单独将AsyncTask另外开辟一个类来写的话,传递的参数又会有不同。

再说数据库:根据实现效果中的第3点要求:搜索过的商品不能重复,并且最新搜索的放置在第一位,所以设计表的时候一定要带上时间,时间的取值也就是System.currentTimeMillis();
数据库中的关键代码如下:

public void addOrUpdate(String hotword){
        SQLiteDatabase db = helper.getWritableDatabase();
        String sql = "select id from t_words where hotword = ? ";
        Cursor cursor = db.rawQuery(sql, new String[]{hotword});
        if(cursor.getCount()>0){
            //说明数据库中已经有数据:更新数据库的时间:
            String sql_update = "update t_words set updatetime = ? where hotword = ? ";
            db.execSQL(sql_update, new String[]{System.currentTimeMillis()+"",hotword});
        }else{
            //直接插入一条记录:
            String sql_add = "insert into t_words(hotword,updatetime) values (?,?);";
            db.execSQL(sql_add, new String[]{hotword,System.currentTimeMillis()+""});
        }

        cursor.close();
        db.close();
    }
public List<SearchDBData> findAll(){
        List<SearchDBData> data = new ArrayList<SearchDBData>();;
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.query("t_words", null, null, null, null, null, "updatetime desc");

        //遍历游标,将数据存储在
        while(cursor.moveToNext()){
            SearchDBData searchDBData = new SearchDBData();
            searchDBData.id = cursor.getInt(cursor.getColumnIndex("id"));
            searchDBData.hotword = cursor.getString(cursor.getColumnIndex("hotword"));
            searchDBData.updatetime = cursor.getLong(cursor.getColumnIndex("updatetime"));
            data.add(searchDBData);
        }
        cursor.close();
        db.close();
        return data;
    }

另外:以下是点击事件中的代码,特别要注意2点:(1)往集合中增加数据的时候先清空下集合,避免数据越加越多(2)数据有变更的时候,需要notify下,保持界面的更新。

            dao.addOrUpdate(hotword);
            findAllList.clear();
            findAllList = dao.findAll();
            adapter.notifyDataSetChanged();

你可能感兴趣的:(Android经验)