I have a RecyclerView displaying CardViews, which are expandable and retractable. I also have a LinearLayout of an ImageView and two Text Views displayed above it. I want to scroll the RecyclerView along with the LinearLayout.
I achieved it using NestedScrollView, but when I expand the CardViews, the view is not able to entirely scroll through the others, at least on my emulator. For example, I have 16 card views, closed on default, and I am able to scroll through the screen. If I open view 1, I can only scroll to view 10, if I open view 2, I can only scroll to view 5 and I can no longer scroll down. I have tried to apply the advice I have read through some posts, but I have yet solved this problem. Here are the following codes:
Sorry for any obvious mistakes, I am fairly new to Android development. Thanks for any response, I appreciate it.
MainActivity
package vn.edu.usth.wikiapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.appbar.AppBarLayout;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
List<Versions> versionsList;
Toolbar toolbar;
public DrawerLayout drawerLayout;
public ActionBarDrawerToggle actionBarDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
toolbar = findViewById(R.id.toolbar);
initData();
setRecyclerView();
// drawer layout instance to toggle the menu icon to open
// // drawer and back button to close drawer
drawerLayout = findViewById(R.id.my_drawer_layout);
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.nav_open, R.string.nav_close);
// pass the Open and Close toggle for the drawer layout listener
// to toggle the button
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
// to make the Navigation drawer icon always appear on the action bar
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void setRecyclerView() {
VersionsAdapter versionsAdapter = new VersionsAdapter(versionsList);
recyclerView.setAdapter(versionsAdapter);
recyclerView.setHasFixedSize(true);
recyclerView.setNestedScrollingEnabled(false);
}
private void initData() {
versionsList = new ArrayList<>();
versionsList.add(new Versions("Code name 1", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 2", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 3", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 4", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 5", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 6", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 7", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 8", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 9", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 10", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 11", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 12", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 13", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 14", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 15", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
versionsList.add(new Versions("Code name 16", "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.n" +
"n"));
}
@Override
public void onPause() {
// Always call the superclass method first
super.onPause();
Log.i("Weather Activity","onPause() finished");
}
@Override
public void onResume() {
// Always call the superclass method first
super.onResume();
Log.i("Weather Activity","onResume() finished");
}
@Override
public void onStop() {
// Always call the superclass method first
super.onStop();
Log.i("Weather Activity","onStop() finished");
}
@Override
public void onDestroy() {
// Always call the superclass method first
super.onDestroy();
Log.i("Weather Activity","onDestroy() finished");
}
public void onCustomToggleClick(View view) {
Toast.makeText(this, "CustomToggle", Toast.LENGTH_SHORT).show();
}
public void onClickSearch(View view) {
Toast.makeText(this, "Search custom", Toast.LENGTH_SHORT).show();
}
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Versions
package vn.edu.usth.wikiapp;
public class Versions {
private String codeName, description;
private boolean expandable;
public boolean isExpandable() {
return expandable;
}
public void setExpandable(boolean expandable) {
this.expandable = expandable;
}
public Versions(String codeName, String description) {
this.codeName = codeName;
this.description = description;
this.expandable=false;
}
public String getCodeName() {
return codeName;
}
public void setCodeName(String codeName) {
this.codeName = codeName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Versions{" +
"codeName='" + codeName + ''' +
", description='" + description + ''' +
'}';
}
}
VersionsAdapter
package vn.edu.usth.wikiapp;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class VersionsAdapter extends RecyclerView.Adapter<VersionsAdapter.VersionVH> {
List<Versions> versionsList;
public VersionsAdapter(List<Versions> versionsList) {
this.versionsList = versionsList;
}
@NonNull
@Override
public VersionVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false);
return new VersionVH(view);
}
@Override
public void onBindViewHolder(@NonNull VersionVH holder, int position) {
Versions versions = versionsList.get(position);
holder.codeNameTxt.setText(versions.getCodeName());
holder.descriptionTxt.setText(versions.getDescription());
boolean isExpandable = versionsList.get(position).isExpandable();
holder.expandable_layout.setVisibility(isExpandable ? View.VISIBLE : View.GONE);
holder.imgView.setImageResource(isExpandable ? R.drawable.ic_up : R.drawable.ic_down);
}
@Override
public int getItemCount() {
return versionsList.size();
}
public class VersionVH extends RecyclerView.ViewHolder {
TextView codeNameTxt, descriptionTxt;
ImageView imgView;
LinearLayout linearLayout;
LinearLayout expandable_layout;
public VersionVH(@NonNull View itemView) {
super(itemView);
codeNameTxt= itemView.findViewById(R.id.code_name);
descriptionTxt = itemView.findViewById(R.id.desc);
imgView = itemView.findViewById(R.id.openCloseArrow);
linearLayout = itemView.findViewById(R.id.linear_layout);
expandable_layout = itemView.findViewById(R.id.expandable_layout);
linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Versions versions = versionsList.get(getAbsoluteAdapterPosition());
versions.setExpandable(!versions.isExpandable());
notifyItemChanged(getAbsoluteAdapterPosition());
}
});
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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=".MainActivity"
android:background="@color/black"
android:id="@+id/my_drawer_layout"
tools:ignore="HardcodedText"
>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
>
<com.google.android.material.appbar.MaterialToolbar
style="@style/Widget.MaterialComponents.Toolbar.Primary"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_menu"
app:title="GeeksforGeeks"
android:id="@+id/toolbar"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="16dp"
>
<TextView
android:layout_width="24dp"
android:layout_height="24dp"
android:textOff=""
android:textOn = ""
android:background="@drawable/ic_search"
android:layout_alignParentRight="true"
></TextView>
<ToggleButton
android:layout_width="24dp"
android:layout_height="24dp"
android:textOff=""
android:textOn=""
android:background="@drawable/toggle_selector"
android:layout_alignParentRight="true"
android:layout_marginRight="36dp"
></ToggleButton>
</RelativeLayout>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@drawable/fork"
android:scaleType="centerCrop"
>
</ImageView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fork"
android:textStyle="bold"
android:textSize="24dp"
android:textColor="@color/white"
>
</TextView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Utensil to spear food"
android:textColor="#CCD1D1"
android:textSize="18dp"
>
</TextView>
</LinearLayout>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recyclerView"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:nestedScrollingEnabled="false"
>
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/navigation_menu"
app:headerLayout="@layout/nav_header_main"
android:background="@color/black"
app:itemTextColor="@color/white"
>
</com.google.android.material.navigation.NavigationView>
<!-- this the navigation view which draws and shows the navigation drawer -->
<!-- include the menu created in the menu folder -->
</androidx.drawerlayout.widget.DrawerLayout>
row.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/linear_layout"
android:orientation="vertical"
android:background="@color/black"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/code_name"
android:text = "Code name"
android:textSize="20dp"
android:padding="12dp"
android:gravity="center_vertical"
android:textColor="@color/white"
android:textStyle="bold"
>
</TextView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_down"
android:padding="12dp"
android:layout_alignParentEnd="true"
android:id="@+id/openCloseArrow"
>
</ImageView>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/expandable_layout"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/desc"
android:text="Version"
android:paddingRight="16dp"
android:paddingLeft="16dp"
android:textColor="@color/white"
android:textSize="16dp"
>
</TextView>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
2
Answers
this solution is work for me
just you remove two line code form your activity
and remove one line code from recycler view xml
You have to set WRAP_CONTENT height to the very first child of Nested Scrollview.