使用PullToRefreshListView代替ChatFragment里的SwipeRefreshLayout时出现的界面适配问题
于是我写了个简单的demo,里面只有一个Activity,fragment。fragment布局上有个TextView充当TitleBar,下方有个EditText充当输入框,中间有个PullToRefreshListView充当聊天内容。当最外层布局为RelativeLayout时,随着键盘的弹出/收回,界面可以自适应。但是当最外层的布局为LinearLayout时,输入框被挤上去之后,就下不来了。到此,不敢说是PullToRefreshListView在fragment里有问题,因为毕竟这个控件的使用量非常大,如果有问题,不可能google不到同样的问题的。
最终在StackOverflow上发现一篇文章:点击http://stackoverflow.com/questions/25303285/activity-with-fragments-does-not-resize-when-the-keyboard-opens?answertab=votes#tab-top
这篇文章中提到了键盘弹出界面适配的原理:
1.如果界面上包含ListView,ScrollView,应用会缩放这两个view的尺寸以显示全部的内容。2.如果这方法不可用,则滚动整个view,以确保当前获取焦点的view不被遮挡。但是LinearLyout是不支持滚动的,所以1和2都无效。
When the soft keyboard appears on the screen, the amount of space available for the application's UI reduces. The system makes decision on how to organize the available space between the application's UI and soft keyboard.
If the window content contains ListView, ScrollView, the application's window is resized provided all the content is visible.
If re-sizing is not feasible, pan and scan approach is used, which simply involves scrolling the application's window so that the currently focused view is visible.
Since your layout does not contain any ListView, ScrollView, re-sizing is ruled out.
The window's root view is a FrameLayout to which you were originally adding LinearLayout. Since LinearLayout does not support scrolling, pan and scan approach is also ruled out. Hence wrapping the layout inside ScrollView solves the scrolling issue.
于是我想到了如果让RelativeLayout加上可以滚动的属性,是不是就能解决问题了。我的chatFragment布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:background="#f2f0eb" >
<com.hyphenate.easeui.widget.EaseTitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:titleBarBackground="#F15645"
app:titleBarLeftImage="@drawable/back_icon"
app:titleBarRightImage="@drawable/ic_share" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/input_menu"
android:layout_below="@id/title_bar" >
<****.ease.widget.ChatMessageListLife
android:id="@+id/message_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<****.ease.widget.VoiceRecorderViewLife
android:id="@+id/voice_recorder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="invisible" />
</RelativeLayout>
<com.hyphenate.easeui.widget.EaseChatInputMenu
android:id="@+id/input_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</RelativeLayout>
ChatMessageListLife是继承自EaseChatMessageList
package *****.ease.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ListView;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.hyphenate.easeui.widget.EaseChatMessageList;
import ******.R;
public class ChatMessageListLife extends EaseChatMessageList {
protected static final String TAG = "EaseChatMessageList";
private PullToRefreshBase<ListView> ptrListView;
public ChatMessageListLife(Context context, AttributeSet attrs, int defStyle) {
this(context, attrs);
}
public ChatMessageListLife(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChatMessageListLife(Context context) {
super(context);
}
protected void init(Context context) {
this.context = context;
LayoutInflater.from(context).inflate(
R.layout.ease_chat_message_list_life, this);
ptrListView = (PullToRefreshBase<ListView>) findViewById(R.id.listView1);
listView = ptrListView.getRefreshableView();
}
public PullToRefreshBase<ListView> getRefreshListView() {
return ptrListView;
}
}
R.layout.ease_chat_message_list_life就是我替换PullToRefreshListView的布局:
<?xml version="1.0" encoding="utf-8"?>
<com.handmark.pulltorefresh.library.PullToRefreshListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ptr="http://schemas.android.com/apk/res-auto"
android:id="@+id/listView1"
style="@style/pulltorefresh_style"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transcriptMode="alwaysScroll"
ptr:ptrMode="pullFromStart" >
</com.handmark.pulltorefresh.library.PullToRefreshListView>
现在重新回到chatFragment布局。最外层是RelativeLayout,于是我尝试着在chatFragment布局聊天内容的RelativeLayout中增加了
android:scrollbars="vertical"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/input_menu"
android:layout_below="@id/title_bar"
[b]android:scrollbars="vertical"[/b] >
<****.ease.widget.ChatMessageListLife
android:id="@+id/message_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<****.ease.widget.VoiceRecorderViewLife
android:id="@+id/voice_recorder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="invisible" />
</RelativeLayout>
这个属性。谢天谢地,it works.