0

I am totally new in the world of Android development and have some trouble to understand how a RecycleViewAdapter works with a CardView when the CardView is a Fragment. I was trying to understand the example on https://github.com/firebase/quickstart-android/blob/master/database/README.md but since they are using a lot of stuff which is related to Firebase I tried to port this to my own example.

I want to have a list which contains several cards just like this:

enter image description here

However, the user should be able to add and remove different cards. At the beginning the view should be empty and if the user press the floating button on the right corner

enter image description here

a new card should be created.

enter image description here

I've just ported the way I thought it should work. Unfortunately, when I press the button nothing is happening (of course the Hello World is printed).

Thanks for you help.

Here is the code of my MainActivity:

package com.example.dynamicfragment;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends AppCompatActivity
{

    private FragmentManager fragmentManager;
    private FragmentTransaction fragmentTransaction;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fragmentManager = getFragmentManager();
        fragmentTransaction = fragmentManager.beginTransaction();
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

       FloatingActionButton fab = findViewById(R.id.fab);
       fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                System.out.println("Hello World");
                fragmentTransaction.add(new CardListFragment(), "CardListFragment");
            }
        });
        fragmentTransaction.commit();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        int id = item.getItemId();
        if (id == R.id.action_settings)
        {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
  }

This is the class who extend the CardListFragment:

  package com.example.dynamicfragment;


  import android.os.Bundle;
  import android.app.Fragment;
  import android.support.v7.widget.LinearLayoutManager;
  import android.support.v7.widget.RecyclerView;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;

  import com.example.dynamicfragment.adapter.CardAdapter;
  import com.example.dynamicfragment.model.Party;

  import java.util.ArrayList;

  public class CardListFragment extends Fragment
  {
      private static final String TAG = "CardListFragment";

      private RecyclerView mRecycler;
      private LinearLayoutManager mManager;
      private CardAdapter mAdapter;

      @Override
      public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
      {
          super.onCreateView(inflater, container, savedInstanceState);
          View rootView = inflater.inflate(R.layout.fragment_card_list, container, false);
          mRecycler = rootView.findViewById(R.id.messagesList);
          mRecycler.setHasFixedSize(true);
          ArrayList<Party> demo = new ArrayList<>();
          demo.add(new Party(0,"Demo", R.drawable.ic_action_account_circle_40));
          this.mAdapter = new CardAdapter(demo);
          return rootView;
      }

      @Override
      public void onActivityCreated(Bundle savedInstanceState)
      {
          super.onActivityCreated(savedInstanceState);
          mManager = new LinearLayoutManager(getActivity());
          mManager.setReverseLayout(true);
          mManager.setStackFromEnd(true);
          mRecycler.setLayoutManager(mManager);
          mRecycler.setAdapter(null);
      }

      @Override
      public void onStart()
      {
          super.onStart();
          if (null != mAdapter)
          {
              //mAdapter.startListening();
          }
      }

      @Override
      public void onStop()
      {
          super.onStop();
          if (null != mAdapter)
          {
              //mAdapter.stopListening();
          }
      }

  }

Here is the code of my data model:

package com.example.dynamicfragment.model;

import java.util.Objects;

public class Party
{
    private int id;
    private String name;
    private int image;

    public Party(int id, String name, int image)
    {
        this.id = id;
        this.name = name;
        this.image = image;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Party party = (Party) o;
        return id == party.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

}

Here is my Adapater class:

package com.example.dynamicfragment.adapter;

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 com.example.dynamicfragment.R;
import com.example.dynamicfragment.model.Party;

import java.util.ArrayList;

public class CardAdapter extends RecyclerView .Adapter<CardAdapter.CardViewHolder>
{

    private ArrayList<Party> dataList;

    public static class CardViewHolder extends RecyclerView.ViewHolder
    {
        TextView partyName;
        ImageView imageViewIcon;

        public CardViewHolder(View itemView)
        {
            super(itemView);
            this.partyName = (TextView) itemView.findViewById(R.id.postAuthor);
            this.imageViewIcon = (ImageView)     itemView.findViewById(R.id.postAuthorPhoto);
        }
    }

    public CardAdapter(ArrayList<Party> data)
    {
        this.dataList = data;
    }

    @Override
    public CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.card_view, parent, false);

        return new CardViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final CardViewHolder holder, final int    listPosition)
    {
        TextView partyName = holder.partyName;
        ImageView imageView = holder.imageViewIcon;
        partyName.setText(dataList.get(listPosition).getName());
        imageView.setImageResource(dataList.get(listPosition).getImage());
    }

    @Override
    public int getItemCount()
    {
        return dataList != null ? dataList.size() : 0;
    }

}

Content files:

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=".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" />

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

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

    <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>

content_main.xml:

<?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout 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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/activity_main">

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

</android.support.constraint.ConstraintLayout>

fragment_card_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/messagesList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:clipToPadding="false"
        android:padding="5dp"
        android:scrollbars="vertical"
        tools:listitem="@layout/card_view" />

</FrameLayout>

card_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp">

        <include
            android:id="@+id/postAuthorLayout"
            layout="@layout/include_post_author"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true" />

        <LinearLayout
            android:id="@+id/starLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/postAuthorLayout"
            android:layout_alignParentRight="true"
            android:layout_alignTop="@+id/postAuthorLayout"
            android:gravity="center_vertical"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/star"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="5dp"
                android:background="?attr/selectableItemBackground"
                android:src="@drawable/ic_toggle_star_outline_24" />

            <TextView
                android:id="@+id/postNumStars"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                tools:text="7" />

        </LinearLayout>

        <include layout="@layout/include_post_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/postAuthorLayout"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="10dp" />

    </RelativeLayout>

</android.support.v7.widget.CardView>

include_post_author.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/postAuthorPhoto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_action_account_circle_40" />

    <TextView
        android:id="@+id/postAuthor"
        style="@style/Base.TextAppearance.AppCompat.Small"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:gravity="center_vertical"
        tools:text="someauthor@email.com" />

</LinearLayout>

include_post_text.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">

    <TextView
        android:id="@+id/postTitle"
        style="@style/TextAppearance.AppCompat.Medium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="1"
        android:textStyle="bold"
        tools:text="My First Post" />

    <TextView
        android:id="@+id/postBody"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        tools:text="Hallo Welt" />

</LinearLayout>
  • you need call fragment transaction out side of the fab click action – Aravind V Mar 01 '19 at 13:39
  • @AravindV I just tried what you mentioned and put the method **fragmentTransaction.add(new CardListFragment(), "CardListFragment");** directly ob in the on create method but above the command **FloatingActionButton fab = findViewById(R.id.fab);** So now when the onCreate method of MainAcitvity is called it creates an object of CardListFragment. However, the view is still empty. And wouldn't this be odd ? Because it should be possible to add a Fragment dynamically to view. – Der edle weiße Ritter Mar 01 '19 at 13:47
  • I think your code is completely wrong you have to add fragment to FrameLayout only just follow this link it will help's you https://www.survivingwithandroid.com/2013/04/android-fragment-transaction.html – Aravind V Mar 01 '19 at 14:01
  • I will try this way as well. But I guess it should work with an RecycleView as well cause that is what google is doing in this demo code: https://github.com/firebase/quickstart-android/tree/master/database/app/src/main/java/com/google/firebase/quickstart/database – Der edle weiße Ritter Mar 01 '19 at 14:14

1 Answers1

0

@Christoph M. The Fragment Transaction if you want to applu on ui u need to give a FrameLayout Id.

Create a FrameLayout with one id in your main class then attach your fragment to id value

like this below

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

      FirstFragment  fragment = new FirstFragment();
        FragmentTransaction transaction = 
         getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.frame_layout,  fragment);
        transaction.addToBackStack(ConstantVariables.FirstFragment);
        transaction.commit();
}

<?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">

    <FrameLayout
        android:id="@+id/frame_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>
Aravind V
  • 358
  • 2
  • 10