项目要求能够输入四行四列并包含一张图片的输入框,形成的效果类似于单个输入框的那种输入手感,之前有个版本做的三行,用的三个Edittext控制联动的,联动写起来比较麻烦,要考虑的情形有点多,所以这次使用了XRecyclerView来写布局。
代码如下:
package com.zrodo.app.tzxmdb.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.recyclerview.widget.GridLayoutManager;
import com.jcodecraeer.xrecyclerview.XRecyclerView;
import com.zrodo.app.tzxmdb.R;
import com.zrodo.app.tzxmdb.base.BaseAdapter;
import com.zrodo.app.tzxmdb.base.BaseViewHolder;
import com.zrodo.app.tzxmdb.bean.InputBean;
import com.zrodo.app.tzxmdb.utils.glide.ImageUtil;
import java.util.ArrayList;
import java.util.List;
/**
* Created by YJY on 2022/8/5 10:37.
* 文件说明:
*/
public class InputListView extends XRecyclerView {
private InputAdapter adapter;
private Bitmap mBitmap;
private List list = new ArrayList<>();
private List watcher = new ArrayList<>();
private OnContentVerListener mListener;
public InputListView(Context context) {
this(context, null);
}
public InputListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InputListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
GridLayoutManager manager = new GridLayoutManager(context, 4);
setLayoutManager(manager);
setPullRefreshEnabled(false);
setLoadingMoreEnabled(false);
adapter = new InputAdapter(context, null);
setAdapter(adapter);
}
public void setContent(String content, Bitmap bitmap) {
this.mBitmap = bitmap;
list.clear();
if (!TextUtils.isEmpty(content)) {
for (int i = 0; i < content.length(); i++) {
InputBean inputBean = new InputBean();
if (i < content.length()) {
inputBean.num = String.valueOf(content.charAt(i));
}
list.add(inputBean);
}
}
if (adapter != null) {
adapter.notifyDataSetChanged();
}
if (mListener != null) {
mListener.onChangeListen(list);
}
}
public String getList() {
StringBuffer stringBuffer = new StringBuffer();
if (list.size() > 0) {
for (InputBean item : list) {
stringBuffer.append(item.num);
}
}
return stringBuffer.toString().trim();
}
public void setListener(OnContentVerListener listener) {
this.mListener = listener;
}
class InputAdapter extends BaseAdapter {
private int lastPostion = 0;//上一次光标的位置
public InputAdapter(Context context, List list) {
super(context, list);
}
@Override
protected int getLayoutRes(int viewType) {
if (viewType == 0) {
return R.layout.adapter_input_1;
} else {
return R.layout.adapter_input;
}
}
@Override
protected int getViewType(int position, Object o) {
return position;
}
@Override
public int getItemCount() {
return 16;
}
@Override
protected void myViewHolderBind(BaseViewHolder holder, int position, List mList, Object o, int adapterPosition, int itemViewType) {
if (position == 0) {//图片
((ImageView) holder.getView(R.id.iv_bitmap)).setImageBitmap(mBitmap);
} else {
LinearLayout view = (LinearLayout) holder.getView(R.id.ll_input);
EditText et = (EditText) holder.getView(R.id.et_code);
view.setBackground(mContext.getDrawable(lastPostion == position ? R.drawable.shape_input_select : position > list.size() ? R.drawable.shape_input_un_empty : R.drawable.shape_input_un_));
et.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
if (lastPostion != position) {
lastPostion = position;
notifyDataSetChanged();
}
}
}
});
et.setOnKeyListener(null);
et.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL) {
int selectionEnd = et.getSelectionStart();
if (selectionEnd == 0) {
if (list.size() < position) {//删除上一个
if (position != 1) {
lastPostion = list.size() == 0 ? 1 : list.size();
notifyDataSetChanged();
}
} else {
if (position != 1) {
lastPostion = position - 1;
notifyDataSetChanged();
}
}
}
}
return false;
}
});
if (watcher.size() > 0) {
for (TextWatcher item : watcher) {
et.removeTextChangedListener(item);
}
}
if (position > list.size()) {
et.setText("");
} else {
InputBean inputBean = list.get(position - 1);
if (inputBean != null) {
et.setText(inputBean.num);
}
}
if (position == lastPostion) {
if (!et.isFocused()) {
et.requestFocus();
et.setSelection(et.getText().toString().trim().length());
}
} else {
et.clearFocus();
}
TextWatcher textWatcher = 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) {
if (list.size() >= 15 && s.length() > 0) {//当输入内容已经满了15位
if (s.length() > 1) {
InputBean inputBean = list.get(position - 1);
String trim = et.getText().toString().trim().substring(0, 1);
et.setText(inputBean != null ? inputBean.num : trim);
}
} else {
if (TextUtils.isEmpty(s.toString().trim())) {//当按到了删除键
if (list.size() > position - 1) {
list.remove(position - 1);
lastPostion = position == 1 ? 1 : position - 1;
}
} else if (s.toString().length() > 1) {//当输入内容达到了2位
if (list.size() > position - 1) {
InputBean inputBean1 = list.get(position - 1);
inputBean1.num = s.toString().substring(0, 1);
}
InputBean inputBean = new InputBean();
inputBean.num = s.toString().substring(1);
list.add(position, inputBean);
lastPostion = position + 1;
} else {//当只输入了一位
InputBean inputBean = new InputBean();
inputBean.num = s.toString();
if (position > list.size()) {
list.add(inputBean);
lastPostion = list.size() + 1;
} else {
list.add(position - 1, inputBean);
lastPostion = position + 1;
}
}
if (mListener != null) {
mListener.onChangeListen(list);
}
notifyDataSetChanged();
}
}
@Override
public void afterTextChanged(Editable s) {
}
};
watcher.add(textWatcher);
et.addTextChangedListener(textWatcher);
}
}
}
public interface OnContentVerListener {
void onChangeListen(List b);
}
}
布局adapter_input_1
布局adapter_input