【问题标题】:How to add pull to refresh in AppBarLayout如何在 AppBarLayout 中添加拉动刷新
【发布时间】:2017-07-27 14:42:47
【问题描述】:

我发现大部分素材都是在讨论在AppBarLayout下方区域添加“拉动刷新”,比如SwipeRefreshLayout,不知道在AppBarLayout中怎么做,意思是:

下拉时,AppBarLayout 中会出现下拉刷新指​​示器。

如何实现?谢谢

=================更新===================

我终于按照自己的方式解决了。 Here是录制简单UI的视频链接。

关键是我从github重写了appbarlayout-spring-behavior。这真的很有帮助。简单来说,我重写了 AppBarLayoutSpringBehavior,在拖动时添加了 Pull-To-Refresh-Callback,并添加了一些逻辑来显示 pull-to-refresh 动画,防止简单地动画回到原始状态。过了一段时间,然后我告诉行为动画回来。

虽然重写后的代码看起来很难看,但似乎可行。我将重构我的代码以使其干净和模块化

【问题讨论】:

    标签: android android-coordinatorlayout android-appbarlayout


    【解决方案1】:

    我已经写了一个nestrefresh repo,你可以为与 AppBarLayout 相同的标题添加拉刷新。您可以在 ViewPager 中为子项添加拉动刷新或拉动以加载更多内容。如果您只想使用 AppBarLayout,可以在我的仓库中使用 ChildCoordinatorLayout 来包装 AppBarLayout。但是当滚动时,AppBarLayout 无法刷新,因为 AppBarLayout 没有向父级发送滚动事件。所以你可以在 repo 中尝试 RefreshBarLayout。

    【讨论】:

      【解决方案2】:

      我终于按照自己的方式解决了。 Here是录制简单UI的视频链接。

      关键是我从github重写了appbarlayout-spring-behavior。这真的很有帮助。简单来说,我重写了 AppBarLayoutSpringBehavior,在拖动时添加了 Pull-To-Refresh-Callback,并添加了一些逻辑来显示 pull-to-refresh 动画,防止简单地动画回到原始状态。过了一段时间,然后我告诉行为动画回来。

      虽然重写后的代码看起来很难看,但似乎可行。我将重构我的代码以使其干净和模块化

      【讨论】:

      • 能否分享一下AppBarLayoutSpringBehaviour的更新代码?
      【解决方案3】:

      您可以尝试这样的视图层次结构

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      
          <android.support.v4.widget.SwipeRefreshLayout
              android:id="@+id/swipeRefreshLayout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:paddingTop="?attr/actionBarSize">
      
              <android.support.v7.widget.RecyclerView
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:layout_below="@+id/appBar"/>
          </android.support.v4.widget.SwipeRefreshLayout>
      
          <android.support.design.widget.AppBarLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
      
              <android.support.v7.widget.Toolbar
                  android:layout_width="match_parent"
                  android:layout_height="?attr/actionBarSize"/>
          </android.support.design.widget.AppBarLayout>
      </RelativeLayout>
      

      在您的 Java 类中,您可以像这样使用 SwipeRefreshLayout

      swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
      swipeRefreshLayout.setProgressViewOffset(false, 0, (int) (swipeRefreshLayout.getPaddingTop() * 1.5));
      swipeRefreshLayout.setOnRefreshListener(() -> {
          swipeRefreshLayout.setRefreshing(true);
          // long process here
          new Handler().postDelayed(() -> runOnUiThread(() -> swipeRefreshLayout.setRefreshing(false)), 2000);
      });
      

      【讨论】:

        【解决方案4】:

        编辑在 AppBarLayout 中添加了 ProgressBar。

        您需要像您说的那样用 SwipeRefreshLayout 包装 ReyclerView,并将 ProgressBar 添加到自定义工具栏中:

        activity_main.xml

        <?xml version="1.0" encoding="utf-8"?>
        <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context="com.example.myapplication.MainActivity">
        
            <android.support.design.widget.AppBarLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:theme="@style/AppTheme.AppBarOverlay">
        
                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="?attr/colorPrimary"
                    app:popupTheme="@style/AppTheme.PopupOverlay">
        
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:gravity="center">
        
                        <TextView
                            android:layout_width="0dp"
                            android:layout_height="match_parent"
                            android:layout_gravity="start"
                            android:layout_weight="1"
                            android:gravity="start|center"
                            android:text="@string/app_name"
                            android:textColor="@android:color/white" />
        
                        <ProgressBar
                            android:id="@+id/a_main_progress"
                            android:layout_width="24dp"
                            android:layout_height="24dp"
                            android:layout_marginEnd="10dp"
                            android:layout_marginRight="10dp"
                            android:visibility="invisible" />
        
                    </LinearLayout>
                </android.support.v7.widget.Toolbar>
        
            </android.support.design.widget.AppBarLayout>
        
            <android.support.v4.widget.SwipeRefreshLayout
                android:id="@+id/a_main_swipe"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">
        
                <android.support.v7.widget.RecyclerView
                    android:id="@+id/a_main_recycler"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
        
                </android.support.v7.widget.RecyclerView>
        
            </android.support.v4.widget.SwipeRefreshLayout>
        
        </android.support.design.widget.CoordinatorLayout>
        

        您还需要在 MainActivity 中设置监听器:

        MainActivity.java

        public class MainActivity extends AppCompatActivity {
        
            private SwipeRefreshLayout swipeRefreshLayout;
            private ProgressBar progressBar;
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        
                Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
                setSupportActionBar(toolbar);
        
                swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.a_main_swipe);
                progressBar = (ProgressBar) findViewById(R.id.a_main_progress);
        
                swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                    @Override
                    public void onRefresh() {
                        progressBar.setVisibility(View.VISIBLE);
                        Handler handler = new Handler();
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                // Simulates a long running task (updating data)
                                swipeRefreshLayout.setRefreshing(false);
                                progressBar.setVisibility(View.INVISIBLE);
                            }
                        }, 2000);
                    }
                });
        
                MainAdapter mainAdapter = new MainAdapter(Arrays.asList("Hello", "World", "Bye"));
                RecyclerView recyclerView = (RecyclerView) findViewById(R.id.a_main_recycler);
                recyclerView.setAdapter(mainAdapter);
                recyclerView.setLayoutManager(new LinearLayoutManager(this));
                recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
            }
        }
        

        如果您也需要,这是一个简单的适配器代码:

        MainAdapter.java

        public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
        
            private List<String> strings;
        
            public MainAdapter(List<String> strings) {
                this.strings = strings;
            }
        
            @Override
            public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
                View view = layoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
                return new ViewHolder(view);
            }
        
            @Override
            public void onBindViewHolder(ViewHolder holder, int position) {
                holder.bind(strings.get(position));
            }
        
            @Override
            public int getItemCount() {
                return strings != null ? strings.size() : 0;
            }
        
            public static class ViewHolder extends RecyclerView.ViewHolder {
                private final TextView textView;
        
                public ViewHolder(View itemView) {
                    super(itemView);
                    textView = (TextView) itemView.findViewById(android.R.id.text1);
                }
        
                public void bind(String s) {
                    textView.setText(s);
                }
            }
        }
        

        这是更新后的结果:

        【讨论】:

        • 我需要 appbarlayout 中的下拉刷新指​​示器。当 Appbarlayout 移动时,它应该一起移动。
        • 您的意思是作为 AppBarLayout 内的图标?
        • 是的。我可以做这个吗?我发现它比我想象的要复杂
        • 也许我需要编写一个自定义行为来执行此操作。不知道有没有样品
        • 好吧,我编辑了答案,你只需要花一些时间来设计它。
        猜你喜欢
        • 2018-09-20
        • 1970-01-01
        • 2017-03-29
        • 2018-07-17
        • 2012-05-26
        • 1970-01-01
        • 2014-08-26
        • 1970-01-01
        • 2018-02-21
        相关资源
        最近更新 更多