android键盘底部弹出动画,解决:(聊天布局)点击底部EditText 弹出软键盘遮挡住上方RecyclerView的内容,实现软键盘将RecyclerView上移效果...

最终效果:

b5c9f2af3d64d6338ba78651ea5ba0cd.png

我的页面整体是一个LinearLayout 里面由二个部分组成上面是一个协调布局,底部是一个线性布局

811081b68b5c01d8a8b5906ad0976154.png

问题1:点击EditText键盘不会把底部EditText顶上去,怎么解决

方法有很多,我这里给一个方法

根部局设置   android:fitsSystemWindows="true"的属性即可

问题2:点击进入聊天界面总是显示在最底部

当首次进入或者数据集发送改变时,让它总是滑动到最底部即可

mRecyclerView.scrollToPosition(数据集长度 - 1);

问题3:点击EditText弹出软键盘会把RecyclerView的内容遮住,并不会向上移动

曾经采取过的方法

方式1:

第一种:首先在清单文件中的Activity节点增加

android:windowSoftInputMode="adjustResize"

然后

LinearLayoutManager manager = new LinearLayoutManager(context);

manager.setStackFromEnd(true);//设置从底部开始,最新添加的item每次都会显示在最下面

recyclerView.setLayoutManager(manager);

效果:当聊天数据少于一页时,看起来很奇怪!不符合QQ和微信这样的方法!

方式2:

在清单文件中的Activity节点增加

android:windowSoftInputMode="adjustPan"

效果:RecyclerView是整体上移了,但是顶部的Toolbar也被顶出屏幕了。

方式3: 最终办法

参考了:解决RecyclerView实现聊天界面,但点击下面的EditText后弹出的输入法会遮盖RecyclerView内容的方法

微信和QQ的实现方案:

不管我当前在RecyclerView 的哪个位置,只要点击输入框,就会跳回最后一条消息的位置。

那我们只需要在我们点击输入框的时候滚到最后一个位置就可以了。思路就是这样,非常的简单。

那是不是,给EditText设置监听,然后再给recycleview设置 滑动到底部就可以了呢?

当然不行!

问题:当给EditText设置点击监听的时候,发现只弹出了键盘,设置recyclerView的指定滑动并不起作用

mRecyclerView.scrollToPosition(数据集长度 - 1);

原因是什么呢?

我想到的是事件分发机制!!!(个人理解)

第一次点击EditText,View获取焦点后弹出了键盘,并不会再将焦点分发下去(也就是不会走监听的方法了)

第二次点击EditText,就会奇怪的发现为什么?它RecyclerView又可以滑动到底部了呢?(焦点没被消费,走了监听的方法)

解决的办法:

在EditText(View)布局中添加一个GroupView的布局(LinearLayout、RelativeLayout等)

事件分发机制:焦点先会走GroupView才会走View,当GroupView表示消费这个焦点,那么View就不会有焦点了

我们就可以在GroupView中处理点击EditText需要触发的操作

弹出软键盘

实现RecyclerView滑动到底部

随之而来的一些问题:

点击EditText之后不会弹出软件盘了(手动控制键盘弹出和隐藏逻辑)

点击EditText show键盘

滑动RecyclerView 和返回界面时 隐藏hide键盘

逻辑清楚了就好办了。

以下代码copy自:解决RecyclerView实现聊天界面,但点击下面的EditText后弹出的输入法会遮盖RecyclerView内容的方法

布局文件修改如下:

仔细看,我在EditText上增加了一个布局,用他来控制EditText的点击事件(当点击的时候,手动请求焦点)。

看MainActivity里面的操作

public class MainActivity extends AppCompatActivity {

private RecyclerView recyclerView_chat;

private EditText editText_message;

private Button btn_send;

private LinearLayout layout_edit;

private ChatAdapter chatAdapter;

private ArrayListchatArrayList = new ArrayList<>();

Handler handler = new Handler(){

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

switch (msg.what){

case 0:

recyclerView_chat.scrollToPosition(chatArrayList.size()-1);

break;

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

recyclerView_chat = (RecyclerView) findViewById(R.id.recyclerView_chat);

editText_message = (EditText) findViewById(R.id.editText_message);

btn_send = (Button) findViewById(R.id.btn_send);

layout_edit = (LinearLayout) findViewById(R.id.layout_edit);

chatArrayList.add(new Chat("你好啊。",ChatAdapter.TYPE_SEND));

chatArrayList.add(new Chat("你叫什么名字啊?",ChatAdapter.TYPE_SEND));

chatArrayList.add(new Chat("你好,我叫小丽",ChatAdapter.TYPE_RECEIVE));

chatArrayList.add(new Chat("你是哪里人啊?",ChatAdapter.TYPE_SEND));

chatArrayList.add(new Chat("我是湖南长沙人",ChatAdapter.TYPE_RECEIVE));

chatArrayList.add(new Chat("好巧啊,我也是长沙的",ChatAdapter.TYPE_SEND));

chatArrayList.add(new Chat("咱们真有缘分诶",ChatAdapter.TYPE_SEND));

chatArrayList.add(new Chat("我也觉得呢",ChatAdapter.TYPE_RECEIVE));

chatAdapter = new ChatAdapter(MainActivity.this,chatArrayList);

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this);

recyclerView_chat.setLayoutManager(linearLayoutManager);

recyclerView_chat.setAdapter(chatAdapter);

// GroupView的监听

layout_edit.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

//让View 也就是EditText获得焦点

editText_message.requestFocus();

showSoftInput(MainActivity.this, editText_message);

//通过handler保证在主线程中进行滑动操作

handler.sendEmptyMessageDelayed(0,250);

}

});

//触摸recyclerView的监听

recyclerView_chat.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View view, MotionEvent motionEvent) {

//隐藏键盘

hideSoftInput(MainActivity.this, editText_message);

return false;

}

});

}

//弹出键盘

public static void showSoftInput(Context context, View view) {

InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);

imm.showSoftInput(view, InputMethodManager.SHOW_FORCED);

}

//隐藏键盘

public static void hideSoftInput(Context context, View view) {

InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);

imm.hideSoftInputFromWindow(view.getWindowToken(), 0);

}

}

我在这里获得布局文件中新增加的那个View,然后让他来给EditText请求焦点,同时用Handler

sendEmptyMessageDelayed(0,250)方法让recyclerView等一会儿再滑动(此时弹出框已被弹出。

当RecyclerView有Touch事件的时候隐藏掉输入法,这样就可以了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值