0

I have an Activity and two Fragments. The first one is a list of items and the second one is detailed view. Ideally I would like to send String id from Fragment 1 to Fragment 2 (when item is clicked) in order to perform new detail query to the API. However, right now I am so confused I just want to understand where do I set the clicklistener. I've tried in:

Fragment 1's onCreateView:

recyclerView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(activity,"Hello", Toast.LENGTH_SHORT).show();
                Log.v("Fragment1", "CLICK !? CLICK !? CLICK !?  ");
            }
        });

Fragment 1's Adapter - onBindViewHolder

holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context,"Hello", Toast.LENGTH_SHORT).show();
                Log.v("Adapter", "CLICK !? CLICK !? CLICK !?  ");
            }
        });

My activity_main.xml is just a FrameLayout and I have separate xml with just RecyclerView, and template xml's for each fragment

RecyclerView:

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"/>

I have those in my fragment 1's linearlayout (not sure if relevant)

android:clickable="true"
android:focusable="true"

Thank you!

mgerjikov
  • 1
  • 4
  • you can't pass variables from one fragment to another. The only way to achieve it is to store your variable in your activity and get it in your second fragment. Use getter and setter in your MainActivity so you can just set and get your variable easily. – Android Mediocre Sep 05 '17 at 01:11

3 Answers3

0

To be able to handle on click for each item it's the right solution :

Fragment 1's Adapter - onBindViewHolder

holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context,"Hello", Toast.LENGTH_SHORT).show();
                Log.v("Adapter", "CLICK !? CLICK !? CLICK !?  ");
            }
        });

To send information from the fragment to another fragment you must use the activity even more from a adapter.

You can use a Interface as a listener for example:

AdpaterListener.java

public interface AdpaterListener {
    void onItemClick(String id);
}

In your adapter create a AdapterListener variable and a setter:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{

        ...
       // your variables 
       private AdapterListener mListener;  


        // your code


    @Override
    public void onBindViewHolder(ViewHolder Vholder,final int position){
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(context,"Hello", Toast.LENGTH_SHORT).show();
                Log.v("Adapter", "CLICK !? CLICK !? CLICK !?  ");
                mListener.onItemClick(data.get(position).getId()  // you call the listener here
            }
        });

    }

    public void setAdapterListener(AdapterListener listener) {
        mListener = listener
    }
}

Then your activity must implements AdapterListener, once the adapter is created call adapter.setAdapterListener(this) to set the activity as listener. You will retrieve the id in your activity in :

@Override
public void onItemClick(String id) {

}

For passing the id to the next fragment you can follow some good practice here to use a Bundle Best practice for instantiating a new Android Fragment

Hope this helps.

Cochi
  • 2,199
  • 2
  • 12
  • 15
  • Firstly, Thank you for spending time to answer my question. I know that fragments should not communicate directly, and I told my mentor that. He asked me why not (I'm guessing to check if I know) , so I was like well the docs says it, so they can be reusable etc. and the response was your fragments don't need to be reusable in this case. So i don't need the Activity from his point of view. Also my Activity has only onCreate() method. Basically if savedInstance is null I use FragmentManager and add my list fragment. That's all from the Activity, so no adapter there. – mgerjikov Sep 05 '17 at 11:34
  • So where is the adapter ? In the first fragment ? – Cochi Sep 05 '17 at 11:40
  • Yes. In onCreateView – mgerjikov Sep 05 '17 at 11:59
  • Ok , so this is the same thing , you create the interface above, you make your fragment `implements` this interface and set the fragment as listener, this is the first step, once it's done i will you explain the rest – Cochi Sep 05 '17 at 12:08
  • My apologies but I have 2 silly questions. First, does it matter if the interface is declared in separate java file or inside the Adapter. And (this is awkward) I can't figure out what "data" is in the example. – mgerjikov Sep 05 '17 at 12:57
  • It's better to declared the interface in a separate file for readability. "data" represente the list you use in the adapter , but it's maybe not relevant, just pass the id to the onItemClick() method. – Cochi Sep 05 '17 at 13:06
  • Ok, so I made the interface in separate java file. Inside my adapter I made the setter method. Inside onBindViewHolder I made setOnclickListener , and overrode onClick like that mListener.onItemClick(id); , where id is the string I want. Then in my Fragment I implemented the interface and overrode onItemClick to show the toast and log msg... And nothing.. I am about to cry.. I put adapter.setAdapterListener(this) before and after recyclerView.setAdapter(adapter) to see if there will be difference .. Still nothing (left it before setAdapter) – mgerjikov Sep 05 '17 at 13:33
0

In order to reuse the Fragment UI components, you should build each as a completely self-contained, modular component that defines its own layout and behavior. Once you have defined these reusable Fragments, you can associate them with an Activity and connect them with the application logic to realize the overall composite UI.

Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.

Please read this official solution provided by google

Community
  • 1
  • 1
farhan patel
  • 1,490
  • 2
  • 19
  • 30
  • Firstly, Thank you for spending time to answer my question. I know that fragments should not communicate directly, and I told my mentor that. He asked me why not (I'm guessing to check if I know) , so I was like well the docs says it, so they can be reusable etc. and the response was your fragments don't need to be reusable in this case. So i don't need the Activity from his point of view – mgerjikov Sep 05 '17 at 11:38
  • even if you do not want your fragments to be reusable, It is advisable to let the communication run through your activity. Since centralised communication is always better and easy than multiple points of communication and managing them. – farhan patel Sep 05 '17 at 12:25
-1

First, make an interface. It will let the activity communicate between fragments. In the interface, declare your method.

public interface Communicate {


    //create same method in your activity. You will not put any code here.

    public void onButtonPressed();

}

In your main activity you must implement the interface.

public class MainPanelScreen extends AppCompatActivity implements Communicate {

You must declare the same methods in your main activity that you have declared in the interface.

//This code is put in the method's declaration in the main activity//
{....
FragmentOne fragOne = new FragmentOne();
FragmentTwo fragTwo = new FragmentTwo():
}.....
@Override
public void onButtonPressed() {




    //This gets the buttonNumber from the button click
    String temp = fragOne.getButtonNumberVariable();


    //this sends the results to the second fragment.
    //you have to declare this method and its code must be in the fragment.
    fragTwo.showButtonNumber(temp);


}

Set up your onclicklistener in the onActivityCreated() in the first fragment.

Button btn = (Button) getView().findViewById(R.id.btn1);

    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {

            //Here you set the variable that you will get from the main activity.
            buttonNumberVariable = "1";

            //This is the interface being used to fire the method in the main activity. 
            Communicate cm; 
            cm.onButtonPressed();


        }
    });
king_abu1918
  • 284
  • 2
  • 6
  • Firstly, Thank you for spending time to answer my question. I know that fragments should not communicate directly, and I told my mentor that. He asked me why not (I'm guessing to check if I know) , so I was like well the docs says it, so they can be reusable etc. and the response was your fragments don't need to be reusable in this case. So i don't need the Activity from his point of view – mgerjikov Sep 05 '17 at 11:37
  • Isn't `cm` null here? – Mo... Apr 17 '20 at 01:23