仿IOS搜索框
程序员文章站
2024-03-21 12:14:04
...
开发项目时,总是会遇到Android与IOS不一样的地方,比如说搜索框,IOS系统自带的功能真的是相当强大,而且样式好看。当公司要求Android与IOS改成一致的时候,Android一般是做妥协的一方。没办法,人家的确实更加养眼啊。心中一万只草尼玛路过,还是得默默的修改。今天就模仿IOS写了一个搜索框。废话不多说,先上图。
其实就是自定义了一个view继承EditText,然后实现监听。上代码:
public class SearchEditText extends EditText implements View.OnFocusChangeListener, View.OnKeyListener, TextWatcher {
private static final String TAG = "SearchEditText";
// 图标是否默认在左边
private boolean isIconLeft = false;
//是否点击软键盘搜索
private boolean pressSearch = false;
//软键盘搜索键监听
private OnSearchClickListenerAnn onSearchClickListener;
//文字改变监听
private OnAfterTextChangedListenerAnn onAfterTextChangeListener;
private OnBeforeTextChangedListenerAnn onBeforeTextChangedListener;
private OnTextChangedListenerAnn onTextChangedListener;
//焦点改变监听
private OnFocusChangeListenerAnn onFocusChangeListener;
// 控件的图片资源
private Drawable[] drawables;
// 搜索图标和删除按钮图标
private Drawable drawableLeft, drawableDel,drawableDelIcon;
// 记录点击坐标
private int eventX, eventY;
// 控件区域
private Rect rect;
public void setOnBeforeTextChangedListener(OnBeforeTextChangedListenerAnn onBeforeTextChangedListener) {
this.onBeforeTextChangedListener = onBeforeTextChangedListener;
}
public void setOnTextChangedListener(OnTextChangedListenerAnn onTextChangedListener) {
this.onTextChangedListener = onTextChangedListener;
}
public void setOnAfterTextChangeListener(OnAfterTextChangedListenerAnn onAfterTextChangeListener) {
this.onAfterTextChangeListener = onAfterTextChangeListener;
}
public void setOnFocusChangeListener(OnFocusChangeListenerAnn onFocusChangeListener) {
this.onFocusChangeListener = onFocusChangeListener;
}
public void setOnSearchClickListener(OnSearchClickListenerAnn onSearchClickListener) {
this.onSearchClickListener = onSearchClickListener;
}
public SearchEditText(Context context) {
this(context, null);
}
public SearchEditText(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.editTextStyle);
}
public SearchEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs);
}
private void init(Context context, AttributeSet attrs) {
setOnFocusChangeListener(this);
setOnKeyListener(this);
addTextChangedListener(this);
//自定义属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SearchEditText);
drawableLeft = typedArray.getDrawable(R.styleable.SearchEditText_searchIcon);
drawableDelIcon = typedArray.getDrawable(R.styleable.SearchEditText_delIcon);
typedArray.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
// 如果是默认样式,直接绘制
if (isIconLeft) {
if (length() < 1) {
drawableDel = null;
}
this.setCompoundDrawablesWithIntrinsicBounds(drawableLeft, null, drawableDel, null);
super.onDraw(canvas);
} else { // 如果不是默认样式,需要将图标绘制在中间
Drawable[] drawables = getCompoundDrawables();
if (drawables != null) {
drawableLeft = drawables[0];
if (drawableLeft != null) {
float textWidth = getPaint().measureText(getHint().toString());
int drawablePadding = getCompoundDrawablePadding();
int drawableWidth = drawableLeft.getIntrinsicWidth();
float bodyWidth = textWidth + drawableWidth + drawablePadding;
canvas.translate((getWidth() - bodyWidth - getPaddingLeft() - getPaddingRight()) / 2, 0);
}
}
super.onDraw(canvas);
}
}
@Override
public void onFocusChange(View view, boolean hasFocus) {
// 被点击时,恢复默认样式
if (!pressSearch&& TextUtils.isEmpty(getText().toString().trim())) {
isIconLeft = hasFocus;
}
if(onFocusChangeListener!=null){
onFocusChangeListener.onFocusChange(view,hasFocus);
}
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
pressSearch = (keyCode ==KeyEvent.KEYCODE_ENTER);
if (pressSearch && onSearchClickListener != null) {
/*隐藏软键盘*/
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isActive()) {
if(v.getApplicationWindowToken()!=null){
imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
}
}
if (onSearchClickListener!=null){
onSearchClickListener.onSearchClick(v);
}
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 清空edit内容
if (drawableDel != null && event.getAction() == MotionEvent.ACTION_UP) {
eventX = (int) event.getRawX();
eventY = (int) event.getRawY();
Log.i(TAG, "eventX = " + eventX + "; eventY = " + eventY);
if (rect == null) rect = new Rect();
getGlobalVisibleRect(rect);
rect.left = rect.right - drawableDel.getIntrinsicWidth();
if (rect.contains(eventX, eventY)) {
setText("");
}
}
// 删除按钮被按下时改变图标样式
if (drawableDel != null && event.getAction() == MotionEvent.ACTION_DOWN) {
eventX = (int) event.getRawX();
eventY = (int) event.getRawY();
Log.i(TAG, "eventX = " + eventX + "; eventY = " + eventY);
if (rect == null) rect = new Rect();
getGlobalVisibleRect(rect);
rect.left = rect.right - drawableDel.getIntrinsicWidth();
// if (rect.contains(eventX, eventY))
// drawableDel = this.getResources().getDrawable(R.mipmap.edit_delete_pressed_icon);
} else {
// drawableDel = this.getResources().getDrawable(R.mipmap.edit_delete_icon);
}
return super.onTouchEvent(event);
}
@Override
public void afterTextChanged(Editable editable) {
if (this.length() < 1) {
drawableDel = null;
} else {
drawableDel = drawableDelIcon;
}
if(onAfterTextChangeListener!=null){
onAfterTextChangeListener.afterTextChanged(editable);
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
if (onBeforeTextChangedListener!=null){
onBeforeTextChangedListener.beforeTextChanged(arg0,arg1,arg2,arg3);
}
}
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
if(onTextChangedListener!=null){
onTextChangedListener.onTextChanged(arg0,arg1,arg2,arg3);
}
}
}
在styles.xml文件中声明自定义属性:
<declare-styleable name="SearchEditText">
//搜索图标
<attr name="searchIcon" format="reference"/>
//删除图标
<attr name="delIcon" format="reference"/>
</declare-styleable>
下面来看使用:
布局文件:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp">
<com.anyan.diycode.views.SearchEditText
android:id="@+id/searchEditText"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
style="@style/editTextStyle"/>
<TextView
android:id="@+id/tvCancel"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="取消"
android:gravity="center_vertical"
android:textSize="15sp"
android:textColor="#117bed"
android:visibility="gone"
android:paddingStart="15dp"
android:paddingEnd="15dp"/>
</LinearLayout>
activity中做业务逻辑代码:
public class Main2Activity extends AppCompatActivity {
// @BindView(R.id.hotTextView)
// HotTextView hotTextView;
// @BindView(R.id.flowLayout)
// FlowLayout flowLayout;
@BindView(R.id.searchEditText)
SearchEditText searchEditText;
@BindView(R.id.tvCancel)
TextView tvCancel;
// @BindView(R.id.searchView)
// SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ButterKnife.bind(this);
searchEditText.setOnSearchClickListener(new SearchEditText.OnSearchClickListener() {
@Override
public void onSearchClick(View view) {
ToastUtil.showTextShort(Main2Activity.this,"search");
}
});
searchEditText.setOnAfterTextChangeListener(new SearchEditText.OnAfterTextChangeListener() {
@Override
public void afterTextChange(Editable editable) {
ToastUtil.showTextShort(Main2Activity.this,editable.toString());
}
});
searchEditText.setOnSearchFocusChangeListener(new SearchEditText.OnSearchFocusChangeListener() {
@Override
public void onSearchFocusChange(View view, boolean hasFocus) {
if (hasFocus){
tvCancel.setVisibility(View.VISIBLE);
}else{
tvCancel.setVisibility(View.GONE);
}
}
});
tvCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
searchEditText.setText("");
searchEditText.clearFocus();
}
});
}
}
推荐阅读
-
仿IOS搜索框
-
仿IOS样式对话框
-
模拟淘宝搜索框 博客分类: javascript javascriptjquery
-
模拟淘宝搜索框 博客分类: javascript javascriptjquery
-
使用QML实现浮动桌面搜索框 博客分类: Qt QtJavaFXUIUbuntuXP
-
使用QML实现浮动桌面搜索框 博客分类: Qt QtJavaFXUIUbuntuXP
-
用java等语言仿360首页拼音输入全模糊搜索和自动换肤
-
用java等语言仿360首页拼音输入全模糊搜索和自动换肤
-
asp.net下使用jQuery.AutoComplete完成仿淘宝商品搜索自动完成功能(改进了键盘上下选择体验)
-
Android高仿IOS 滚轮选择控件