简体   繁体   中英

SwipeRefresh Layout with RecylerView inside a NestedScrollView

I have created a fragment with a RecyclerView inside a NestedScrollView . I am trying to add swipe to refresh feature inside the app but whenever I add SwipeRefreshLayout inside the NestedScrollView the list items get hidden and the app on running shows only a blank fragment which does also does not refresh on pulling down.

Code for the fragment:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:isScrollContainer="false"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="fill_vertical"
    android:clipToPadding="false">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/blogList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:nestedScrollingEnabled="false" />

</android.support.v4.widget.NestedScrollView>

Code of the base_layout into which the fragment is added as a tab:

<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill"
        />
</android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"  />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/fab_margin"
    app:srcCompat="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

Here you already have 2 scrollable elements and trying to add the third breaks the desired performance. SwipeRefreshLayout with NestedScrollview sholuldn't be used together. Just use RecyclerView with SwipeRefreshLayout and it'll work just fine

Create a SwipeRefreshLayout and a RecyclerView in XML file.

    <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/simpleSwipeRefreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.v4.widget.SwipeRefreshLayout>

Create a new XML file rowlayout.xml for item of RecyclerView and paste the following code in it. In this step we create a new xml file for item row in which we creates a TextView and ImageView to show the data.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dp">
    <!--
    items for a single row of RecyclerView
    -->
    <ImageView
        android:id="@+id/image"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher" />
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:text="ABCD"
        android:textColor="#000"
        android:textSize="20sp" />
</LinearLayout>

Firsly we get the reference of SwipeRefreshLayout and RecyclerView. After that we creates two ArrayList's for Person Names and then we set a LayoutManager and finally we set the Adapter to show the items in RecyclerView. Finally we implement setOnRefreshListener event on SwipeRefreshLayout and in onRefresh() method we shuffle the list items and set the adapter.

import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    SwipeRefreshLayout swipeRefreshLayout;
    RecyclerView recyclerView;
    // ArrayList for person names
    ArrayList personNames = new ArrayList<>(Arrays.asList("Person 1", "Person 2", "Person 3", "Person 4", "Person 5", "Person 6", "Person 7", "Person 8", "Person 9", "Person 10", "Person 11", "Person 12", "Person 13", "Person 14"));
    ArrayList personImages = new ArrayList<>(Arrays.asList(R.drawable.person1, R.drawable.person2, R.drawable.person3, R.drawable.person4, R.drawable.person5, R.drawable.person6, R.drawable.person7, R.drawable.person1, R.drawable.person2, R.drawable.person3, R.drawable.person4, R.drawable.person5, R.drawable.person6, R.drawable.person7));

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // init SwipeRefreshLayout and ListView
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.simpleSwipeRefreshLayout);
        // get the reference of RecyclerView
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        // set a LinearLayoutManager with default vertical orientation
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(linearLayoutManager);
        // call the constructor of CustomAdapter to send the reference and data to Adapter
        CustomAdapter customAdapter = new CustomAdapter(MainActivity.this, personNames, personImages);
        recyclerView.setAdapter(customAdapter); // set the Adapter to RecyclerView
        // implement setOnRefreshListener event on SwipeRefreshLayout
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                // cancel the Visual indication of a refresh
                swipeRefreshLayout.setRefreshing(false);
                shuffleItems();
            }
        });
    }

    public void shuffleItems() {
        // shuffle the ArrayList's items and set the adapter
        Collections.shuffle(personNames, new Random(System.currentTimeMillis()));
        Collections.shuffle(personImages, new Random(System.currentTimeMillis()));
        // call the constructor of CustomAdapter to send the reference and data to Adapter
        CustomAdapter customAdapter = new CustomAdapter(MainActivity.this, personNames, personImages);
        recyclerView.setAdapter(customAdapter); // set the Adapter to RecyclerView
    }
}

Create a new class CustomAdapter.java inside package and add the following code.

 import android.content.Context;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.Toast;
 import java.util.ArrayList;
 public class CustomAdapter extends RecyclerView.Adapter {
 ArrayList personNames;
 ArrayList personImages;
 Context context;
 public CustomAdapter(Context context, ArrayList personNames, ArrayList personImages) {
 this.context = context;
 this.personNames = personNames;
 this.personImages = personImages;
 }
 @Override
 public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 // infalte the item Layout
 View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
 // set the view's size, margins, paddings and layout parameters
 MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder
 return vh;
 }
 @Override
 public void onBindViewHolder(MyViewHolder holder, final int position) {
 // set the data in items
 holder.name.setText(personNames.get(position));
 holder.image.setImageResource(personImages.get(position));
 // implement setOnClickListener event on item view.
 holder.itemView.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 // display a toast with person name on item click
 Toast.makeText(context, personNames.get(position), Toast.LENGTH_SHORT).show();
 }
 });
 }
 @Override
 public int getItemCount() {
 return personNames.size();
 }
 public class MyViewHolder extends RecyclerView.ViewHolder {
 // init the item view's
 TextView name;
 ImageView image;
 public MyViewHolder(View itemView) {
 super(itemView);
 // get the reference of item view's
 name = (TextView) itemView.findViewById(R.id.name);
 image = (ImageView) itemView.findViewById(R.id.image);
 }
 }
 }

Now run the App and pull down to refresh the content in RecyclerView.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM