模仿手机浏览器,点击Edittext,同时出现搜索历史和软键盘

最近项目中有个需求,在点击一个edittext的输入框的时候,要出现一个展示搜索历史的view,如果有2条以上的,就先显示2条,点击对应按钮,可以展示全部搜索历史。最多保存、显示5条。最开始的时候,打算用popupwindow,但是,会和系统的软键盘冲突。在onclick事件中,如果要想同时弹出搜索历史popupwindow和软键盘,会导致出现一个问题:点击edittext的时候,显示中文输入法键盘,然后,自动切换到英文输入法。此时,还不能再输入内容。用了很多办法,哪怕是handler的延时弹出popupwindow,也不行。最后,决定,不用popupwindow。就是点击的时候,出现一个listview,软键盘会自动出现。


预览图:
这里写图片描述
这里写图片描述

tips:主布局中的“保存”等按钮,不要用Button,要不然,listview出现的时候,反而会被这些Button压在下面。但是用其他的,就不会


具体代码实现(不再多做说明了,注释很详细了):
Listview适配器的item用的布局
option_item_2:

<?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="vertical"
    >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00aa00"
        android:gravity="center_vertical"
        >

        <ImageView
            android:id="@+id/delImage"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:src="@mipmap/ic_launcher"
            android:textSize="15dp"/>

        <TextView
            android:id="@+id/item_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_toLeftOf="@id/delImage"
            android:paddingBottom="10dp"
            android:paddingLeft="5dp"
            android:paddingTop="10dp"
            android:textColor="#333333"
            android:textSize="14sp"/>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/show_all_history_or_cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/show_all_history"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="10dp"
            android:paddingBottom="10dp"
            android:paddingTop="10dp"
            android:text="全部搜索记录"
            android:textColor="#888888"
            android:textSize="14sp"/>

        <TextView
            android:id="@+id/cancel_history"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_gravity="center"
            android:layout_marginRight="10dp"
            android:paddingBottom="10dp"
            android:paddingTop="10dp"
            android:text="关闭"
            android:textColor="#888888"
            android:textSize="14sp"/>

    </RelativeLayout>

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

OptionsAdapter_2

package com.chen.customviewdemo.adapter;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.chen.customviewdemo.R;
import com.chen.customviewdemo.listener.HandleListviewItemListener;
import com.chen.customviewdemo.utils.CHEN;

import java.util.ArrayList;

/**
 * 适配器
 */
public class OptionsAdapter_2 extends BaseAdapter {
    private ArrayList<String> list = new ArrayList<String>();
    private Activity activity = null;

    private HandleListviewItemListener handleListviewItemListener;

    /**
     * 自定义构造方法
     *
     * @param activity
     * @param list
     */
    public OptionsAdapter_2(Activity activity, HandleListviewItemListener listener, ArrayList<String> list) {
        this.activity = activity;
        this.list = list;
        handleListviewItemListener = listener;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    class ViewHolder {
        TextView textView;
        ImageView imageView;
        TextView show_all_history;
        TextView cancel_history;
        RelativeLayout show_all_history_or_cancel;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            holder = new ViewHolder();
            //下拉项布局
            convertView = LayoutInflater.from(activity).inflate(R.layout.option_item_2, null);
            holder.textView = (TextView) convertView.findViewById(R.id.item_text);
            holder.imageView = (ImageView) convertView.findViewById(R.id.delImage);
            holder.show_all_history = (TextView) convertView.findViewById(R.id.show_all_history);
            holder.cancel_history = (TextView) convertView.findViewById(R.id.cancel_history);
            holder.show_all_history_or_cancel = (RelativeLayout) convertView.findViewById(R.id.show_all_history_or_cancel);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        if (CHEN.HideShowAllSearchHistory && list.size() == 2 && position == 1) {
            holder.show_all_history_or_cancel.setVisibility(View.VISIBLE);
        } else {
            holder.show_all_history_or_cancel.setVisibility(View.GONE);
        }

        if (position == list.size() - 1) {
            holder.show_all_history_or_cancel.setVisibility(View.VISIBLE);

            if (CHEN.HideShowAllSearchHistory) {
                //说明有2个以上的搜索历史记录
                holder.show_all_history.setVisibility(View.VISIBLE);
            } else {
                holder.show_all_history.setVisibility(View.GONE);
            }

        }

        /**
         * 显示全部搜索记录
         */
        holder.show_all_history.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handleListviewItemListener.handleListviewItem("showAllSearchHistory", -1);
            }
        });

        /**
         * 关闭搜索记录提示
         */
        holder.cancel_history.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handleListviewItemListener.handleListviewItem("cancelSearchHistoryTip", -1);
            }
        });

        holder.textView.setText(list.get(position));

        //为下拉框选项文字部分设置事件,最终效果是点击将其文字填充到文本框
        holder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handleListviewItemListener.handleListviewItem("setSelestData", position);
            }
        });

        //为下拉框选项删除图标部分设置事件,最终效果是点击将该选项删除
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!CHEN.HideShowAllSearchHistory) {
                    handleListviewItemListener.handleListviewItem("delSelestData", position);
                }
            }
        });
        return convertView;
    }
}

Activity的布局activity_main_9

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="#EEEED1"
    >

    <EditText
        android:id="@+id/edittext"
        android:layout_width="200dp"
        android:layout_height="40dp"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="50dp"
        android:background="#dedede"
        android:paddingLeft="3dp"
        android:singleLine="true"/>


    <TextView
        android:id="@+id/save"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:layout_below="@id/edittext"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="30dp"
        android:text="保存"
        android:textColor="#000000"
        android:textSize="20sp"/>

    <TextView
        android:id="@+id/show"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:layout_below="@id/save"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="30dp"
        android:text="展示"
        android:textColor="#000000"
        android:textSize="20sp"/>

    <TextView
        android:id="@+id/clear"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:layout_below="@id/show"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="30dp"
        android:text="清空"
        android:textColor="#000000"
        android:textSize="20sp"/>


    <ListView
        android:id="@+id/search_history_lv"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_below="@id/edittext"
        android:layout_marginLeft="30dp"
        android:background="#ffffff"
        android:visibility="gone"/>

</RelativeLayout>

MainActivity_9

package com.chen.customviewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import com.chen.customviewdemo.adapter.OptionsAdapter_2;
import com.chen.customviewdemo.listener.HandleListviewItemListener;
import com.chen.customviewdemo.utils.CHEN;
import com.chen.customviewdemo.utils.SharedPreferencesUtil;
import com.chen.customviewdemo.utils.Utils;

import java.util.ArrayList;


public class MainActivity_9 extends Activity implements View.OnClickListener, HandleListviewItemListener {

    //下拉框选项数据源
    private ArrayList<String> datas;
    //文本框
    private EditText et;
    //保存输入过的数据
    private TextView save_input_data;
    //用于展示数据的
    private TextView show_pop;
    //清理数据
    private TextView clear;
    //保存搜索数据
    SharedPreferencesUtil spUtil;
    //展示搜索历史的listview
    ListView search_history_lv;
    //适配器
    private OptionsAdapter_2 adapter;

    /**
     * 临时存放数据的
     */
    private ArrayList<String> tempDatas;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_9);

        spUtil = new SharedPreferencesUtil(MainActivity_9.this);
        datas = new ArrayList<String>();
        tempDatas = new ArrayList<String>();

        search_history_lv = (ListView) findViewById(R.id.search_history_lv);
        adapter = new OptionsAdapter_2(this, this, datas);
        search_history_lv.setAdapter(adapter);

        //初始化界面组件
        et = (EditText) findViewById(R.id.edittext);

        clear = (TextView) findViewById(R.id.clear);
        clear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                datas.clear();
                spUtil.saveSearchKeyHistory("");
            }
        });

        save_input_data = (TextView) findViewById(R.id.save);
        //设置点击事件,恢复下拉框列表数据,没有什么作用,纯粹是为了方便多看几次效果而设置
        save_input_data.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //编辑框输入的数据
                String willSave = et.getText().toString().trim();
                if (!TextUtils.isEmpty(willSave)) {
                    String saveData = spUtil.getSearchKeyHistory();

                    if (TextUtils.isEmpty(saveData)) {
                        //说明之前没有搜索历史,直接存放当前的搜索数据
                        spUtil.saveSearchKeyHistory(willSave);
                    } else {
                        if (!Utils.isContainsStr(saveData, willSave)) {
                            //已有数据中,不包含新的搜索内容,把最新搜索内容加到最前面
                            saveData = willSave + "-" + saveData;
                        } else {
                            //已有数据中,包含新的搜索内容,要重新排序,把最新的搜索内容,放在最前面
                            String[] oldOrder = saveData.split("-");
                            int equaseIndex = 0;
                            for (int i = 0; i < oldOrder.length; i++) {
                                if (oldOrder[i].equals(willSave)) {
                                    equaseIndex = i;
                                    break;
                                }
                            }
                            if (equaseIndex != 0) {
                                //新的搜索内容,不在保存数据的第一条。(如果在第一条,就不用处理了)
                                saveData = oldOrder[equaseIndex];
                                for (int j = 0; j < equaseIndex; j++) {
                                    saveData = saveData + "-" + oldOrder[j];
                                }
                                for (int k = equaseIndex + 1; k < oldOrder.length; k++) {
                                    saveData = saveData + "-" + oldOrder[k];
                                }
                            }

                        }
                        //项目中,输入框默认的一次最多输入数据是20个字。5条数据是100字。这里再多加点。这里正确的处理,应该是保证只保存5条。这里偷个懒,不在详细写了。
                        if (saveData.length() > 150) {
                            saveData = saveData.substring(0, 150);
                        }
                        spUtil.saveSearchKeyHistory(saveData);
                    }
                }
            }
        });

        show_pop = (TextView) findViewById(R.id.show);
        show_pop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSearchHistory();
            }
        });

        et.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("chen", "onClick---");
                if (TextUtils.isEmpty(et.getText().toString().trim())) {
                    showSearchHistory();
                }
            }
        });

    }

    /**
     * 显示搜索历史
     */
    public void showSearchHistory() {

        datas.clear();
        String data = spUtil.getSearchKeyHistory();
        if (!TextUtils.isEmpty(data)) {
            if (data.contains("-")) {
                String[] dList = data.split("-");
                int length = dList.length > 5 ? 5 : dList.length;
                for (int i = 0; i < length; i++) {
                    if (!TextUtils.isEmpty(dList[i])) {
                        datas.add(dList[i]);
                    }
                }
            } else {
                datas.add(data);
            }
        }

        if (datas != null && datas.size() > 0) {
            if (datas.size() > 2) {
                CHEN.HideShowAllSearchHistory = true;
                tempDatas.clear();
                tempDatas.addAll(datas);

                //如果有多条,默认显示前2条。上面已经保存到临时的里面了,这里就可以把2条以后的数据清理掉
                for (int i = datas.size() - 1; i >= 2; i--) {
                    datas.remove(i);
                }
            }
            adapter.notifyDataSetChanged();
            search_history_lv.setVisibility(View.VISIBLE);
        }

    }

    @Override
    public void onClick(View v) {
    }

    @Override
    public void handleListviewItem(String flag, int index) {

        //给Edittext设置选中的内容
        if ("setSelestData".equals(flag)) {
            et.setText(datas.get(index));
            search_history_lv.setVisibility(View.GONE);

        }
        //删除选择条目
        if ("delSelestData".equals(flag)) {
            datas.remove(index);
            tempDatas.clear();
            tempDatas.addAll(datas);

            //刷新下拉列表
            adapter.notifyDataSetChanged();

            if (datas == null || datas.size() == 0) {
                spUtil.saveSearchKeyHistory("");
            } else {
                if (datas.size() == 1) {
                    spUtil.saveSearchKeyHistory(datas.get(0));
                } else {
                    String temp = "";
                    for (int j = 0; j < datas.size(); j++) {
                        temp = temp + datas.get(j) + "-";
                    }
                    if (temp.endsWith("-")) {
                        temp = temp.substring(0, temp.length() - 1);
                    }
                    spUtil.saveSearchKeyHistory(temp);
                }
            }

        }

        //展示所有搜索历史
        if ("showAllSearchHistory".equals(flag)) {
            CHEN.HideShowAllSearchHistory = false;
            datas.clear();
            datas.addAll(tempDatas);
            adapter.notifyDataSetChanged();
        }

        //关闭展示所有搜索历史
        if ("cancelSearchHistoryTip".equals(flag)) {
            CHEN.HideShowAllSearchHistory = false;
            search_history_lv.setVisibility(View.GONE);
        }
    }
}

处理listview中某个条目的监听接口
HandleListviewItemListener

package com.chen.customviewdemo.listener;

/**
 * 处理listview中某个条目的监听接口
 */
public interface HandleListviewItemListener {

    void handleListviewItem(String flag, int index);
}

用到的工具:

package com.chen.customviewdemo.utils;

import android.app.Activity;
import android.text.TextUtils;
import android.util.DisplayMetrics;

/**
 * 工具类
 */
public class Utils {
    /**
     * 判断一个大的string里面,是否包含另一个小的string
     *
     * @param mianStr 大的string(主string)
     * @param data    要判断的string
     * @return true表示包含,false表示不包含
     */
    public static boolean isContainsStr(String mianStr, String data) {

        try {
            if (checkStringIsEmpty(mianStr) || checkStringIsEmpty(data)) {
                return false;
            } else {
                if (mianStr.contains("-")) {
                    boolean b = false;
                    String[] arr = mianStr.split("-");

                    for (int i = 0; i < arr.length; i++) {
                        if (data.equals(arr[i])) {
                            b = true;
                        }
                    }
                    return b;
                } else {
                    if (mianStr.equals(data)) {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
        } catch (Exception e) {
            return false;
        }
    }
}

全局变量

package com.chen.customviewdemo.utils;

/**
 * 用于保存全局变量值
 */
public class CHEN {

    /**
     * 是否隐藏“全部搜索记录”
     */
    public static boolean HideShowAllSearchHistory = false;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值