How to use a Fragment button

Asked

Viewed 2,343 times

0

I have a button in my Ragment

fragment_main

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="@+id/fragMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="16dp"
tools:context="makerapp.android.minhastarefas.MainActivity.ListItensFragment">



<!-- Exibe nome da lista atual -->
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:weightSum="1">

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="54dp">

        <Button
            style="?android:attr/buttonStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/stringVolta"
            android:id="@+id/anterior" />

    </RelativeLayout>

</LinearLayout>


<View
    android:layout_width="match_parent"
    android:layout_height="1dip"
    android:background="@color/md_grey_300"/>

<!-- Lista de itens -->
<makerapp.android.minhastarefas.ui.DynamicListView
    android:id="@+id/itens_listview"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:divider="@color/md_grey_300"
    android:dividerHeight="1dp"
    android:choiceMode="singleChoice"
    android:headerDividersEnabled="true"/>

<!-- Layout a ser exibido quando a lista estiver vazia -->
<FrameLayout
    android:id="@android:id/empty"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:drawablePadding="16dp"
        android:drawableTop="@drawable/ic_empty_list"
        android:fontFamily="sans-serif-light"
        android:gravity="center"
        android:text="@string/empty_list_text"
        android:textAppearance="?android:textAppearanceMedium"
        android:textColor="@color/secondary_text_color"
        android:textSize="20dp"
        android:textStyle="italic" />

</FrameLayout>

<!-- Layout destinado a publicidade-->
<FrameLayout
    android:id="@+id/ad_framelayout"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content">
    <LinearLayout
        android:orientation="horizontal"
        android:id="@+id/ad_linear_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </LinearLayout>
</FrameLayout>

and want to access this button in the Mainactivity class

Mainactivity

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

    Button btAnterior = (Button)findViewById(R.id.anterior);

    btAnterior.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.e("TAG","ta aki");
        }
    });
}

This way there is giving this mistake.

java.lang.RuntimeException: Unable to start activity ComponentInfo{makerapp.android.minhastarefas/makerapp.android.minhastarefas.MainActivity}: java.lang.NullPointerException

How do I catch the event by clicking this button in this class?

  • You can catch this event inside Fragment, after inflating the layout, and notify your Activity.

  • i even managed to use inside the Fragment more I needed a method of this class ai when I tried to use so Mainactivity main = new Mainactivity(); main.metodo() gave error because some variables used in this method are started in oncreate

  • So it won’t work, never install a Activity, Android already does this and manages the life cycle. Use the Observer standard to notify Activity, I’ll create an answer.

  • ta good ........

3 answers

3


To notify the Activity in order to no longer have coupling, use the standard Observer/Listener.

1. Create an interface that has all the events that can occur on Fragment and which depend on another class(s) (s).

public interface FragmentListener {
    public void metodo(); // Metodo que sera chamado
}

2. Deploy the interface in your Activity or any other class you want to use:

public SuaActivity extends Activity implements FragmentListener {
    @Override
    public void metodo() {
        // Implementação
    }
}

3. Create a property to store an object that implements that interface in your Fragment:

public class SeuFragment extends Fragment {
    private FragmentListener mListener;

    // Getters e Setters omitidos
}

4. Use the interface when the button is clicked:

btAnterior.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(mListener != null) mListener.metodo();
    }
});

5. Move the implementation of this interface to Fragment:

// Se a Activity implementar, voce pode usar o metodo onAttach do Fragment para setar
public void onAttach(Activity a) {
    super.onAttach(a);

    if(a instanceof FragmentListener) {
        mListener = (FragmentListener) a;
    }
}

// Ou com um setter
public void setFragmentListener(FragmentListener listener) {
    mListener = listener;
}

6. Release the interface instance when the Fragment is destroyed, thus avoiding Memory Leak:

public void onDestroy() {
    super.onDestroy();
    mListener = null;
}

// ou
public void onDestroyView() {
    super.onDestroyView();
    mListener = null;
}

// ou quando for dettached
public void onDetach() {
    super.onDetach();
    mListener = null;
}
  • I didn’t understand the mListener of item 5

  • The mListener is the attribute listener, I’ll edit.

  • after I asked I realized kkk , It worked thank you very much

0

You can expose the btAnterior as follows. In your fragment you can write something similar:

private View view;
private TextView btAnterior;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    this.view = inflater.inflate(...);
    this.btAnterior = (Button)findViewById(R.id.anterior);
    ...
}

public TextView getBtAnterior() {
    return this.btAnterior;
}

In your Mainactivity, you can access your website as follows:

private SparseArray<Fragment> fragments = new SparseArray<Fragment>();
private ListItensFragment fragmentListItens;

@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);
    this.fragments.put(fragment.getId(), fragment);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    this.fragmentListItens = (ListItensFragment)this.fragments.get(R.id.fragmentListItens);
    this.fragmentListItens.getBtAnterior().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.e("TAG","ta aki");
        }
    });
    ...
}

0

Just to update in case anyone else needs it. I solved this problem by doing so:

Within the fragment class( before):

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_dom, container, false);
}

Inside the fragment class( After):

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_dom, container, false);
    listView = (ListView) view.findViewById(R.id.ID_ListView_test);
    // Inflate the layout for this fragment
    return view;
}

I take what is returned by default from the Fragment class and play in a "view" variable. And I use this variable to access the methods I would have in an Activity class, like findViewById. In the case of Button, you do the same thing I did with listview and then use the normal Bt.setOnClickListner as if you were in an Activity. I don’t know if it’s right, but it’s what worked for me.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.