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.