自定义EditText的使用(一键删除)|ListView item中多edittext问题

在实际开发的时候,应用的登录界面和注册界面通常会用到这个,我说的就是EditText末尾处的那个叉号,当输入EditText中的内容不符合自己的意愿,想全部删除的时候,可以点击那个叉号实现一键删除EditText里面的全部内容。效果图如下:

这里写图片描述

当然,EditText里的内容为null的时候,这个叉号是不能显示的,只有输入内容才允许显示。
有些人会有疑问,包括我一开始的时候也是,为啥要用自定义?直接在xml里设置图片资源,先隐藏,再判断当EditText不为null的时候再将叉号显示出来,不也能实现这样的效果?
答案是:确实也能实现效果,但是没有考虑到复用性。你想想,一个应用的登录界面和注册界面可能会有很多EditText,然后每一个EditText你都需要在xml设置好图片资源先隐藏,然后再判断是不是null,而且还得响应点击事件,代码量会不会很大,是不是在重复一些没必要的代码?

所以,用到自定义EditText,这样的好处就是,不仅在当前项目可以用,以后在别的项目,遇到这个需求的时候,也可以拿过来直接用,起到了完美封装的作用~~
OK了!废话不多说了!自定义EditText代码如下:

public class MyEditText extends EditText implements View.OnFocusChangeListener , TextWatcher {
    private Drawable mClearDrawable;
    public MyEditText(Context context) {
            this(context,null);
    }

    public MyEditText(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.editTextStyle);
    }

    public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mClearDrawable = getResources().getDrawable(R.drawable.close);//设置一键清除EditText里内容的叉号资源图片
        mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
        setClearIconVisible(false);
        this.setOnFocusChangeListener(this);
        this.addTextChangedListener(this);
    }
    /**
     * 当输入框里面内容发生变化的时候回调的方法
     */
    @Override
    public void onTextChanged(CharSequence s, int start, int count, int after) {
        setClearIconVisible(s.length() > 0);
    }
    /**
     * 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
     */
    protected void setClearIconVisible(boolean visible) {
        Drawable right = visible ? mClearDrawable : null;
        setCompoundDrawables(getCompoundDrawables()[0],
                getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
    }
    /**
     * 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
     * 当我们按下的位置在EditText的宽度 - 图标到控件右边的间距 - 图标的宽度和
     * EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向没有考虑
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (getCompoundDrawables()[2] != null) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                boolean touchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable.getIntrinsicWidth())
                        && (event.getX() < ((getWidth() - getPaddingRight())));
                if (touchable) {
                    this.setText("");
                }
            }
        }
        return super.onTouchEvent(event);
    }
    /**
     * 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
     */
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            setClearIconVisible(getText().length() > 0);
        } else {
            setClearIconVisible(false);
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
}

——————————————————————————————————————————————————————————
下面看一下小程序中是如何实现的。也很简单,不解释。清空的功能主要就是动态传递一个空字符串过去就行了 哈哈哈~
wxml

<view class='input_container'>
  <image class='icon_search' src='../../image/icon_search.png' bindtap='searchContent'></image>
  <input placeholder='输入内容' bindinput='getValue' value='{{inputValue}}' confirm-type='search' bindconfirm='search'></input>
  <image class='icon_delete' src='../../image/icon_delete.png' bindtap='clearValue' hidden='{{!showDeleteIcon}}' ></image>
</view>

wxss:

.input_container {
  display: -webkit-flex;
  display: flex;
  height: 24px;
  border: 1px solid #ccc;
  align-items: center;
  margin: 20px;
  padding-left: 10px;
  padding-top: 4px;
  padding-bottom: 4px;
}

.icon_search {
  width: 20px;
  height: 20px;
  margin-right: 6px;
}

input {
  height: 20px;
  flex: 1;
  font-size: 14px;
}

.icon_delete {
  width: 20px;
  height: 20px;
  padding-right: 20px;
}

js:

var value = '';
Page({

  /**
   * 页面的初始数据
   */
  data: {
    showDeleteIcon: false,//是否显示叉号图标
    inputValue: ''//input中的值
  },

  //判断输入框是否有值
  getValue: function (e) {
    value = e.detail.value
    if (value != '') {
      this.setData({
        showDeleteIcon: true
      });
    } else {
      this.setData({
        showDeleteIcon: false
      });
    }
  },

  //清空输入框中的值
  clearValue: function () {
    this.setData({
      inputValue: '',
      showDeleteIcon: false
    });
  },

  //搜索
  search:function(e){
      wx.showToast({
        title: e.detail.value,
      })
  },
})

效果图如下:
这里写图片描述
——————————————————————————————————————————————————————————————
下面说一下ListView item项中多edittext的问题,下面以一个Edittext为例进行说明。多个同理。
有时候,我们项目需求会遇到ListView中多edittext同时提交的需求。当用到ListView复用上下滚动时,难免会出现输入框已经输入过的内容出现错乱的情况。

主要就是在adapter的getView()中数据绑定的地方进行设置:

        //绑定数据
        final ThemeTalkerBean bean = list.get(position);
        //为了保存已经输入过的信息,需要先清除监听
        if (item.et_talker_name.getTag() instanceof TextWatcher) {
            item.et_talker_name.removeTextChangedListener((TextWatcher) item.et_talker_name.getTag());
        }


        TextWatcher talkerWatcher = 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) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (TextUtils.isEmpty(s)) {
                    bean.setTalkerName("");
                } else {
                    bean.setTalkerName(s.toString());
                }
            }
        };
        item.et_talker_name.addTextChangedListener(talkerWatcher);
        item.et_talker_name.setTag(talkerWatcher);

ThemeTalkerBean 这个bean就是用来保存每个item中edittext输入的内容的。最好提交的时候,提交bean里面的信息就行了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,如果姓名本来就在ListView中,您可以按照以下步骤来实现点击姓名拨打对应电话号码的功能: 1. 创建一个ListView布局,用于显示联系人的姓名和电话号码。 2. 创建一个自定义的Adapter类,用于将姓名和电话号码显示在ListView中。 3. 在Adapter类中的getView()方法中,为ListView的每个列表项添加一个OnClickListener,当用户点击姓名时,使用隐式Intent拨打对应的电话号码。 下面是一个简单的示例代码片段,用于实现上述功能: ```java public class ContactListAdapter extends BaseAdapter { private List<Contact> contactList; private Context context; // 构造函数 public ContactListAdapter(Context context, List<Contact> contactList) { this.context = context; this.contactList = contactList; } @Override public View getView(final int position, View convertView, ViewGroup parent) { // 获取ListView中的每个列表项布局 View view = LayoutInflater.from(context).inflate(R.layout.list_item, null); // 获取姓名和电话号码的TextView控件 TextView nameTextView = view.findViewById(R.id.nameTextView); TextView phoneTextView = view.findViewById(R.id.phoneTextView); // 显示姓名和电话号码 final Contact contact = contactList.get(position); nameTextView.setText(contact.getName()); phoneTextView.setText(contact.getPhone()); // 为姓名的TextView控件添加OnClickListener nameTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 使用隐式Intent拨打电话 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + contact.getPhone())); context.startActivity(intent); } }); return view; } // 其他方法省略 } ``` 在上述示例代码中,ContactListAdapter类是自定义的Adapter类,用于将姓名和电话号码显示在ListView中。在getView()方法中,为每个列表项添加一个OnClickListener,当用户点击姓名时,使用隐式Intent拨打对应的电话号码。在OnClickListener中,使用ACTION_DIAL操作和电话号码URI来创建一个拨打电话的隐式Intent,然后使用startActivity()方法启动该Intent。 请注意,ACTION_DIAL操作只会打开拨号器应用程序,并自动填充电话号码,但不会直接拨打电话。如果您想要直接拨打电话,应使用ACTION_CALL操作,但是需要注意用户的权限授权问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值