3

Hello I'm new to android studio (3.2), and I'm trying to get a recycler view to show a scrollable list of my custom views. However, it shows a static, un-scrollable duplicated background of my views in the background of my recycler view. It looks like this(before I scroll it): enter image description here

Then a static background appears behind my views after I start to scroll: enter image description here

Is this a problem with my recycler view's adapter or the xml file? Also, I'm building this recycler view inside a fragment.

my adapter:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder> {
   private ArrayList<CardItem> card_item_list;

   // view holder is created from the recycler_card_item template
   public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
       public TextView title_tv, date_tv;
       public RecyclerViewHolder(LinearLayout layout) {
            super(layout);
            title_tv = layout.findViewById(R.id.card_item_title);
            date_tv = layout.findViewById(R.id.card_item_date);
       }
   }

   // take in a list of card items to initialize with
   public RecyclerAdapter(ArrayList<CardItem> card_list) {
        card_item_list = card_list;
   }

    @NonNull
    @Override
    // inflate and creates a viewholder objects, which is from the recycler care item template;
    public RecyclerAdapter.RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
       // create a new card item
        LinearLayout cardLayout = (LinearLayout) LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.recycler_card_item, viewGroup, false);
        RecyclerViewHolder vh = new RecyclerViewHolder(cardLayout);
        return vh;
    }

    @Override
    // bind the CardItem class with the viewholder to complete the card
    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
       CardItem target_card = card_item_list.get(position);
       holder.title_tv.setText(target_card.title);
       holder.date_tv.setText(target_card.date);
    }

    @Override
    public int getItemCount() {
        return card_item_list.size();
    }
}

and my reycler view's xml file:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/recycler_view_item" />

</android.support.constraint.ConstraintLayout>

Here's the code for the fragment:

public class RecycleFragment extends Fragment {
    private RecyclerView recyclerView;
    private RecyclerView.Adapter viewAdapter;
    private RecyclerView.LayoutManager viewLayouManager;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.recycler_fragment, container, false);
        recyclerView = rootView.findViewById(R.id.recycler_view);
        // get and configure the recycle view
        recyclerView.setHasFixedSize(true);
        // layout manager for recyler view
        viewLayouManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(viewLayouManager);
        // creates the initial cards
        ArrayList<CardItem> card_lists = new ArrayList<>();
        for (int i = 0;i<7;i++){
            CardItem card = new CardItem("TODO"+i,"12/" + i);
            card_lists.add(card);
        }
        // adapter for recycler view, initialize the recycler view
        viewAdapter = new RecyclerAdapter(card_lists);
        recyclerView.setAdapter(viewAdapter);
        return rootView;
    }
}

My code for my activity:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sidebar);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        // starts the recycle view in the content
        RecycleFragment recycleFragment = new RecycleFragment();
        getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, recycleFragment).commit();
    }

The activity_sidebar.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_sidebar"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_sidebar"
        app:menu="@menu/activity_sidebar_drawer" />

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

Here's the app_bar_sidebar.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=".Sidebar">

    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        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="@android:color/holo_green_dark"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

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

    <include layout="@layout/content_sidebar"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        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's the content_sidebar.xml that has the fragment:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_sidebar"
    tools:context=".Sidebar">

    <fragment
        android:id="@+id/fragment_container"
        android:name="com.steven97102gmail.todoassistant.RecycleFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.511"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
Steven97102
  • 334
  • 5
  • 17
  • 1
    Please post the code where you are adding the `Fragment` to activity. – aminography Dec 22 '18 at 05:11
  • I mean your activity code, how do you add the fragment to activity. I think you add the fragment twice. – aminography Dec 22 '18 at 05:17
  • What exactly is the `fragment_container` element in the `activity_sidebar` layout? A ``? A ``, maybe? – Mike M. Dec 22 '18 at 05:31
  • the fragment lives in a constraint_layout, which is included in the activity_sidebar – Steven97102 Dec 22 '18 at 05:35
  • No, what is the specific tag that has ID `fragment_container`? – Mike M. Dec 22 '18 at 05:36
  • Sorry, it does not help :-| post the `app_bar_sidebar.xml` please. – aminography Dec 22 '18 at 05:38
  • Sorry don't quite get what do you mean. If you mean what has the ID fragment container, then it is the fragment that I started the recycler view. – Steven97102 Dec 22 '18 at 05:40
  • In your layout XML, what kind of tag is the `android:id="@+id/fragment_container"` attribute on? A ``? – Mike M. Dec 22 '18 at 05:41
  • I posted the app_bar_sidebar.xml, and yes it is an attribute on a fragment – Steven97102 Dec 22 '18 at 05:42
  • yes the android:id="@+id/fragment_container" attribute is on a fragment – Steven97102 Dec 22 '18 at 05:45
  • 1
    A `` element is not just a placeholder for a `Fragment`. It actually causes a `Fragment` instance to be loaded in that spot during inflation in the `setContentView()` call. Change it to a ``. – Mike M. Dec 22 '18 at 05:45
  • Can you post it as an answer to clarify what do you mean? Thanks a lot. – Steven97102 Dec 22 '18 at 05:48
  • 1
    I mean, just change ` – Mike M. Dec 22 '18 at 05:50
  • 1
    It works! Thanks, Didn't know that fragment is already and instance to be loaded. – Steven97102 Dec 22 '18 at 05:52
  • No problem. Yep, a `` element creates what's commonly referred to as a static `Fragment` instance. Its creation and transactions will be handled for you automatically, but you cannot remove or replace it at runtime. Unfortunately, though, you can still add your own `Fragment`s into it dynamically, so it often causes confusion for users who are new to `Fragment`s. Just some FYI. Glad you got it working. Cheers! – Mike M. Dec 22 '18 at 05:55

2 Answers2

2

Please use replace instead of add when you want to attach the fragment to the activity. It may cause adding a new fragment over the previous one in activity recreation such as device rotation.

// starts the recycle view in the content
RecycleFragment recycleFragment = new RecycleFragment();

getSupportFragmentManager()
    .beginTransaction()
    .replace(R.id.fragment_container, recycleFragment)
    .commit();
aminography
  • 21,986
  • 13
  • 70
  • 74
0

Try this

public class RecycleFragment extends Fragment {
    private RecyclerView recyclerView;
    private RecyclerView.Adapter viewAdapter;
    private RecyclerView.LayoutManager viewLayouManager;
    private View rootView;    

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (rootView != null) return rootView;
        rootView = inflater.inflate(R.layout.recycler_fragment, container, false);
        recyclerView = rootView.findViewById(R.id.recycler_view);
        // get and configure the recycle view
        recyclerView.setHasFixedSize(true);
        // layout manager for recyler view
        viewLayouManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(viewLayouManager);
        // creates the initial cards
        ArrayList<CardItem> card_lists = new ArrayList<>();
        for (int i = 0;i<7;i++){
            CardItem card = new CardItem("TODO"+i,"12/" + i);
            card_lists.add(card);
        }
        // adapter for recycler view, initialize the recycler view
        viewAdapter = new RecyclerAdapter(card_lists);
        recyclerView.setAdapter(viewAdapter);
        return rootView;
    }
}
Liar
  • 1,235
  • 1
  • 9
  • 19