上一篇文章已经讲过,关于edittext切换焦点,将光标设置到最后一位的问题。有兴趣的朋友可以看我上一篇文章
今天主要讲recyclerview中多行多列的edittext切换及切换下一个item中的edittext问题
先看看在不加任何处理的情况下的edittext在recyclerview中切换效果(当然,edittext的前提需要设置singleline=true,maxlines=1,这样才能激活键盘中的切换下一项功能)
从图中大家可以看到,在没有任何处理的情况下,光标直接切换到底部的edittext,而不是我们期望的下一个edittext。究其原因,是因为键盘的“下一项”触发的是“nextfocusdown”事件,因为默认的键盘定义中只存在nextfocusleft,nextfocusright,nextfocusup,nextfocusdown,即上下左右。如果我们要切换到我们期望的下一个 需要在上一个设置nextFocusDown属性,指定切换的控件的id
例子 : nextFocusDown= @+id/edit2
接下来看效果
从图中可以看到,点击切换的时候,虽然是按我设置的顺序切换,但是没有切换到下一个itemview中。这是因为我在最后一个Edittext中设置了 nextFocusDown= @+id/edit1,所有到最后一个的时候就切换到了第一个。接下来去掉最后一个edittext中的设置看效果
从图中可以看到,在第一个itemview中的最后一个edittext切换时,并没有切换到下一个itemview中的第一个edittext,依然还是切换到了它底部的edittext。那么改如何解决这个问题呢
这里就需要重写LinearLayoutManager中的 onInterceptFocusSearch
先说一下代码逻辑,onInterceptFocusSearch相当于是焦点切换的监听。在这个方法中,我们先获取当前焦点的itemview的下标且不是最后一个,然后判断edittext是否为itemview中的最后一个,满足这些条件时,获取下一个itemview中的第一个edittext并返回,这就能成功解决了此问题
直接上代码
public class FocusLinearlayoutManager extends LinearLayoutManager {
public FocusLinearlayoutManager(Context context) {
super(context);
}
@Nullable
@Override
public View onInterceptFocusSearch(@NonNull View focused, int direction) {
if(focused instanceof EditText){
EditText editText = ((EditText) focused);
//光标移入文件末尾
editText.setSelection(editText.getText().length());
}
switch (direction) {
case View.FOCUS_DOWN:
//单个列表的最后一个
if(isLast((EditText) focused,(ViewGroup)getFocusedChild())){
for(int i = 0 ; i < getItemCount(); i ++){
if(getChildAt(i) == getFocusedChild()){
if(i < getItemCount() - 1){
View firstEdit = getFirstEdit((ViewGroup) getChildAt(i + 1));
return firstEdit;
}
break;
}
}
}
}
return super.onInterceptFocusSearch(focused,direction);
}
/**
* 获取第一个edit
* @param viewGroup
* @return
*/
private View getFirstEdit(ViewGroup viewGroup){
for(int i = 0 ; i < viewGroup.getChildCount() ; i ++){
View view = viewGroup.getChildAt(i);
if(view instanceof EditText){
return view;
}else if(view instanceof ViewGroup){
View firstEdit = getFirstEdit((ViewGroup) view);
if(firstEdit != null) {
return firstEdit;
}
}
}
return null;
}
/**
* 是否为最后一个
* @param editText
* @param viewGroup
* @return
*/
private boolean isLast(EditText editText,ViewGroup viewGroup){
getFocusedChild();
List<EditText> list = new ArrayList<>();
getEdits(list,viewGroup);
if(list.indexOf(editText) == list.size() -1){
return true;
}
return false;
}
/**
* 获取所有edit
* @param list
* @param viewGroup
*/
private void getEdits(List<EditText> list,ViewGroup viewGroup){
for(int i = 0 ; i < viewGroup.getChildCount() ; i ++){
View view = viewGroup.getChildAt(i);
if(view instanceof EditText){
list.add((EditText) view);
}else if(view instanceof ViewGroup){
getEdits(list, (ViewGroup) view);
}
}
}
}
此类 与recyclerview设置layoutmanager代码相同
recyclerView.setLayoutManager(new FocusLinearlayoutManager(mContext));
接下来看效果
最后推荐一个我自己写的MVVM开源项目《Open MVVM》(想加扣扣讨论群请进入文章结尾查看群号)
有问题请私信,留言,或者发送邮件到我扣扣邮箱 qingingrunt2010