Santi Gil Santi Gil - 3 months ago 30
Android Question

Android. Get listview item onClick inner button to new child fragment

I have a Fragment with a ListView of

row
items. A
row
consist in just am
ImageView


fragment_1.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment1">

<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#b5b5b5"
android:dividerHeight="1dp"
android:listSelector="@drawable/list_selector"/>

</RelativeLayout>


row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip">

<!-- Rightend Play Button. -->
<ImageView
android:id="@+id/play_button"
android:layout_width="50dip"
android:layout_height="50dip"
android:src="@drawable/ic_play"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>

</RelativeLayout>


I have a
ResourceCursorAdapter
to fill this
ListView
. I just assign to each ImageView a click listener. It plays a record saved in the provided path.

private abstract class MyAdapter extends ResourceCursorAadpter {

@Override
public void bindView(View view, Context context, final Cursor cursor) {
// Play button.
ImageView playButton = (ImageView) view.findViewById(R.id.play_button);
playButton.setOnClickListener(new View.OnClickListener() {
String record = cursor.getString(cursor.getColumnIndex(DbAdapter.RECORD));
public void onClick(View v) {
// Play record in path [record]. Not the problem.
}
});
}
}


Now I want to open a new fragment
Fragment_2
in a
row
click. This fragment has the same play_button, and has to play the same record.

fragment_2.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_audio"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment2">

<!-- Play Button. -->
<ImageView
android:id="@+id/play_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_play"/>

</RelativeLayout>


How can I manage that this button plays the same record than in
Fragment_1
?
I think I could be able if I have a hidden TextView with the path of the record, but sure you have a smarter solution.

In my
onCreateView
of
Fragment_1
.

mList = (ListView) root.findViewById(R.id.list);
// Click event for single row.
mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO: Go to fragment_2 and has the same view [view.findViewById(R.id.play_button)]
}
});

Answer

Communication between fragments should be done through the associated Activity. You can use interface for this. it Will serve as contract and bridge between them.

Let's have the following components:

An activity hosts fragments and allow fragments communication

FragmentA first fragment which will send data

FragmentB second fragment which will receive datas from FragmentA

FragmentA's implementation is:

public class FragmentA extends Fragment {
  DataPassListener mCallback;
  public interface DataPassListener{
    public void passData(String data);
  }
  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    // Make sure that container activity implement the callback interface
    try {
      mCallback = (DataPassListener)activity;
    } catch (ClassCastException e) {
      throw new ClassCastException(activity.toString()
            + " must implement DataPassListener");
    }
  }
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    // Suppose that when a button clicked second FragmentB will be inflated
    // some data on FragmentA will pass FragmentB
    // Button passDataButton = (Button).........
    passDataButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        if (view.getId() == R.id.passDataButton) {
          mCallback.passData("Text to pass FragmentB");
        }
      }
    });
  }
}

MainActivity implementation is:

public class MainActivity extends ActionBarActivity implements DataPassListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (findViewById(R.id.container) != null) {
        if (savedInstanceState != null) {
            return;
        }
        getFragmentManager().beginTransaction()
                .add(R.id.container, new FragmentA()).commit();
    }
}
@Override
public void passData(String data) {
    FragmentB fragmentB = new FragmentB ();
    Bundle args = new Bundle();
    args.putString(FragmentB.DATA_RECEIVE, data);
    fragmentB .setArguments(args);
    getFragmentManager().beginTransaction()
        .replace(R.id.container, fragmentB )
        .commit();
}
}

FragmentB implementation is:

public class FragmentB extends Fragment{
final static String DATA_RECEIVE = "data_receive";
TextView showReceivedData;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_B, container, false);
    showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
}
@Override
public void onStart() {
    super.onStart();
    Bundle args = getArguments();
    if (args != null) {
        showReceivedData.setText(args.getString(DATA_RECEIVE));
    }
}

https://developer.android.com/training/basics/fragments/communicating.html This document has given information in detail, you can go through it.

In your situation, you can apply this way to communicate between two fragments.

Comments