Nie*_*els 31 android android-listview
我已经实现SwipeRefreshLayout了我的应用程序,但它只能容纳一个应该是listview的直接子项.我试图找出如何将空文本视图添加到以下工作XML文件:
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@+id/listViewConversation"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:dividerHeight="1dp" />
</android.support.v4.widget.SwipeRefreshLayout>
Run Code Online (Sandbox Code Playgroud)
将其包装在线性/相对布局中会使其失灵,因为当您想要向下滑动列表视图时,列表视图将始终更新.我能想到的一种方法是以编程方式进行此操作,但我想这不是最好的选择.
您可以使用本教程学习如何实现它:滑动以刷新GUIDE
所以基本上它一切正常,但我想添加一个空视图,当listview为空时显示一条消息.
Dan*_*ato 52
我不喜欢对一个孩子的限制.此外,SwipeRefreshLayout的当前实现具有ScrollView,ListView和GridView的硬编码"魔术"处理,仅当视图是您自己视图的直接子视图时才触发.
这说好消息是它是开源的,所以你可以复制代码并适应你的需求,或者你可以做我做的事情:
使用两个不同的SwipeRefreshLayout,一个用于Empty视图,另一个用于ListView.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tobrun.example.swipetorefresh.MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout_listView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout_emptyView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<TextView
android:id="@+id/emptyView"
android:text="@string/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center" />
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)
然后告诉列表视图空列表视图是空视图的滑动刷新布局.
现在,当您有数据时,列表视图将自动隐藏空刷新布局,并在列表为空时显示.
列表的滑动刷新布局不应接收触摸事件,因为列表是隐藏的.
祝好运.
and*_*per 31
无需任何解决方法.
您只需使用此视图层次结构:
<FrameLayout ...>
<android.support.v4.widget.SwipeRefreshLayout ...>
<ListView
android:id="@android:id/list" ... />
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:id="@android:id/empty" ...
android:text="@string/empty_list"/>
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)
然后,在代码中,您只需调用:
_listView.setEmptyView(findViewById(android.R.id.empty));
Run Code Online (Sandbox Code Playgroud)
而已.
编辑:如果您希望即使显示空视图也能够刷到刷新,您将不得不以某种方式避免隐藏ListView,因此您可以使用具有此功能的自定义ListView:
@Override
public void setVisibility(final int visibility)
{
if(visibility!=View.GONE||getCount()!=0)
super.setVisibility(visibility);
}
Run Code Online (Sandbox Code Playgroud)
与我编写的解决方案一起,无论您显示多少项目,都会显示刷卡到刷新.
当然,如果你真的想隐藏ListView,你应该改变代码.也许添加"setVisibilityForReal(...)":)
viz*_*izZ 11
实际上,你唯一想到的就是把空TextView包裹着一个可滚动的容器 - 例如ScrollView.有关详细信息,请查看SwipeRefreshLayout.canChildScrollUp()方法及其用法.
无论如何,回到原点.这是一个成功的实施:
activity_some.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:measureAllChildren="true">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/empty" />
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
Run Code Online (Sandbox Code Playgroud)
你empty.xml的基本上是你希望包装的东西ScrollView.
empty.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<TextView
android:text="Nothing here..."
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
Run Code Online (Sandbox Code Playgroud)
现在,为了摆脱着名SwipeRefreshLayout的只刷新时的问题,SwipeRefreshLayout在必要时切换(特定于片段):
private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener;
@Override
public void onStart() {
super.onStart();
mOnScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
int scrollY = mWebView.getScrollY();
if (scrollY == 0)
swipeLayout.setEnabled(true);
else
swipeLayout.setEnabled(false);
}
};
swipeLayout.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener);
}
@Override
public void onStop() {
swipeLayout.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener);
super.onStop();
}
Run Code Online (Sandbox Code Playgroud)
而已!希望能帮助到你!;)
顺便说一句,你为什么会使用SwipeRefreshLayout与FrameLayout这种方式?因为这样您可以执行平滑过渡动画,例如交叉渐变效果,并且您的任何状态视图都可以刷卡(如果您需要统一的提取/刷新/重试机制).
这就是我所做的:我禁用刷卡刷新,除非我的listView已启动.
mBookedProductsListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem == 0)
mSwipeRefreshLayout.setEnabled(true);
else
mSwipeRefreshLayout.setEnabled(false);
}
});
Run Code Online (Sandbox Code Playgroud)
我的Xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:id="@+id/productListLL"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<EditText
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:background="#a4aeb8"
android:drawableRight="@drawable/search_icon"
android:paddingRight="15dp"
android:textColor="@android:color/white"
android:paddingLeft="15dp"
android:hint="Rechercher"
android:textColorHint="@android:color/white"
android:inputType="textCapWords|textNoSuggestions"
/>
<include android:layout_width="match_parent" android:layout_height="wrap_content" layout="@layout/filter_by_categories_buttons" android:id="@+id/categoriesTree" android:layout_below="@id/search" />
<ListView
android:id="@+id/productListLV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@drawable/product_listview_divider"
android:dividerHeight="1dp"
android:scrollbars="none"
android:overScrollMode="never"
android:choiceMode="multipleChoiceModal"
android:background="#e7eaef"
android:visibility="gone"
android:layout_below="@id/categoriesTree"
/>
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
Run Code Online (Sandbox Code Playgroud)
奇迹般有效.
我遇到了同样的问题.令人讨厌的是SwipeRefreshLayout只能有一个AdpaterView子项.
如果为AdpaterView设置了空视图,则在没有可用数据的情况下将其设置为隐藏.但是,SwipeRefreshLayout需要AdpaterView才能工作.因此,我扩展了AdpaterView以使其仍然显示,即使它是空的.
@Override
public void setVisibility(int visibility) {
if (visibility == View.GONE && getCount() == 0) {
return;
}
super.setVisibility(visibility);
}
Run Code Online (Sandbox Code Playgroud)
也许您需要将适配器视图的背景设置为透明.但在我的情况下,它不是必需的,因为空视图是一个简单的TextView.
根据此处的一些答案和 SwipeRefreshLayout 的源代码,我将视图子类化为专门处理 RecyclerView(或 ListView)以及容器内的“空”视图,即子容器。
它需要一个布局,例如
<SwipeRefreshLayoutWithEmpty ...>
<FrameLayout ...>
<TextView android:text="List is Empty" ...>
<RecyclerView ...>
</FrameLayout>
</SwipeRefreshLayoutWithEmpty>
Run Code Online (Sandbox Code Playgroud)
代码是:
public class SwipeRefreshLayoutWithEmpty extends SwipeRefreshLayout {
private ViewGroup container;
public SwipeRefreshLayoutWithEmpty(Context context) {
super(context);
}
public SwipeRefreshLayoutWithEmpty(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean canChildScrollUp() {
// The swipe refresh layout has 2 children; the circle refresh indicator
// and the view container. The container is needed here
ViewGroup container = getContainer();
if (container == null) {
return false;
}
// The container has 2 children; the empty view and the scrollable view.
// Use whichever one is visible and test that it can scroll
View view = container.getChildAt(0);
if (view.getVisibility() != View.VISIBLE) {
view = container.getChildAt(1);
}
return ViewCompat.canScrollVertically(view, -1);
}
private ViewGroup getContainer() {
// Cache this view
if (container != null) {
return container;
}
// The container may not be the first view. Need to iterate to find it
for (int i=0; i<getChildCount(); i++) {
if (getChildAt(i) instanceof ViewGroup) {
container = (ViewGroup) getChildAt(i);
if (container.getChildCount() != 2) {
throw new RuntimeException("Container must have an empty view and content view");
}
break;
}
}
if (container == null) {
throw new RuntimeException("Container view not found");
}
return container;
}
}
Run Code Online (Sandbox Code Playgroud)
完整要点:https : //gist.github.com/grennis/16cb2b0c7f798418284dd2d754499b43
| 归档时间: |
|
| 查看次数: |
25509 次 |
| 最近记录: |