Wie bekomme ich die Symbolleiste aus dem Fragment?

107

Ich habe ActionBarActivitymit NavigationDrawerund benutze support_v7 Toolbarals ActionBar. In einem meiner Fragmente hat die Symbolleiste eine benutzerdefinierte Ansicht. In anderen Fragmenten Toolbarsollte Titel angezeigt werden.

Wie bekomme ich eine ToolbarInstanz zum Anpassen aus Fragmenten? Ich kann ActionBar mit bekommen getActivity().getActionBar(), aber wenn ich setTitle()diese Instanz ActionBar aufrufe, tut es nichts.

UPD:

In meinem Fall

((ActionBarActivity) getActivity()).getSupportActionBar().setTitle();

(wie MrEngineer13 sagte) funktioniert bei der ersten Fragmenterstellung nicht, da ich es von onHiddenChanged () aus aufrufe. Jetzt füge ich onCreateView () weitere hinzu und es funktioniert einwandfrei.

anisart
quelle
Fragmente haben keine Actionbars / Symbolleisten-Aktivitäten
tyczj
(MainAcivity) this.getActivity ()). GetToolbar (); wird die richtige Antwort sein !! um die Symbolleiste in Fragment zu bekommen !!
LOG_TAG

Antworten:

201

Sie müssen Ihre Aktivität von Anfang getActivity()an AppCompatActivityausführen. Hier ist ein Beispiel:

((AppCompatActivity) getActivity()).getSupportActionBar().setTitle();

Der Grund, warum Sie es wirken müssen, ist, dass getActivity()a zurückgegeben wird FragmentActivityund Sie ein benötigenAppCompatActivity

In Kotlin:

(activity as AppCompatActivity).supportActionBar?.title = "My Title"
MrEngineer13
quelle
8
'supportActionBar' und 'toolbar' zu bekommen ist dasselbe?
Darpan
@ Darpan nicht sicher
Konstantin Konopko
Wenn ich dies hinzufüge, ändert sich der Titel. Aber wenn ich zur übergeordneten Aktivität zurückkehre, wie kann ich den Titel erneut ändern? Ich meine, ich habe eine Navigationsschublade. Die seitliche Schublade hat einige Fragmente und die Hauptaktivität hat einen eigenen Titel. Wenn ich den Titel der Hauptaktivität festlege, funktioniert es und in Fragmenten hat die von Ihnen erwähnte Art perfekt funktioniert. Aber wie soll ich den Titel der Aktivität bei der Rückkehr ändern?
Kylo Ren
82

Falls Fragmente eine benutzerdefinierte Ansicht von ToolBar haben sollten, können Sie ToolBar für jedes Fragment separat implementieren.

ToolBar in fragment_layout hinzufügen:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimaryDark"/>

finde es in Fragment:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);
        Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);

        //set toolbar appearance
        toolbar.setBackground(R.color.material_blue_grey_800);

        //for crate home button
        AppCompatActivity activity = (AppCompatActivity) getActivity();
        activity.setSupportActionBar(toolbar);
        activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

Der Menü-Listener kann auf zwei Arten erstellt werden: überschreiben Sie onOptionsItemSelected in Ihrem Fragment:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()){
        case android.R.id.home:
            getActivity().onBackPressed();
    }
    return super.onOptionsItemSelected(item);
}

oder legen Sie den Listener für die Symbolleiste fest, wenn Sie diese in onCreateView () erstellen:

toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                return false;
            }
        });
Flinbor
quelle
1
Ich möchte nur bestätigen, dass dies der richtige Weg ist. Wenn wir ein anderes Fragment mit einer Symbolleiste in Viewpager + Tablayout oder Pagertabstripe laden, wirkt sich dies auf die App-Leistung beim Wischen aus.
LOG_TAG
1
@LOG_TAG Ich habe ein Schubladen-Design, bei dem jedes Fragment die Symbolleiste implementiert (und somit eine Symbolleiste in der Layoutdatei hat), und der obige Code hat für mich hervorragend funktioniert.
MattBoothDev
Vielen Dank! Arbeitete wie HEYUL !! :) Übrigens ist es besser, übergeordnete Aktivitäten onOptionsItemSelected()anstelle von Fragmenten zu überschreiben , um Code-Wiederholungen zu vermeiden.
Aditya Naique
@ChadMx nein, warum schrieb er überhaupt über das Hinzufügen von Symbolleisten in XML und so weiter. Der Autor fragte, wie die Symbolleiste programmgesteuert aus dem Fragment abgerufen werden kann. Also stackoverflow.com/a/26998718/4548520 das ist die beste / richtige Antwort und es ist kurz
user25
43

Sie haben zwei Möglichkeiten, um die Symbolleiste fragmentiert zu erhalten

Erster

Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);

und zweiter

Toolbar toolbar = ((MainActivity) getActivity()).mToolbar;
Bhargav Thanki
quelle
Aber ist das der richtige Weg? Weil wir auch getSupportedActionBar haben?
Code_Life
9
toolbar = (Toolbar) getView().findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);
Danial
quelle
2

Für Kotlin-Benutzer (activity as AppCompatActivity).supportActionBar?.show()

Muhamed Riyas M.
quelle
!!ist völlig vermeidbar mit ?und es wird Ihnen einen möglichen Absturz
ersparen
Ich glaube, das ist besser(activity as? AppCompatActivity)?.supportActionBar?.show()
JonZarate
1

Möglicherweise müssen Sie versuchen, getActivity().getSupportActionBar().setTitle()wenn Sie support_v7 verwenden.

Wang
quelle
1

Aus Ihrem Fragment: (Symbolleiste aus Fragment holen?)

// get toolbar
((MainAcivity)this.getActivity()).getToolbar();  // getToolbar will be method in Activity that returns Toolbar!!  don't use getSupportActionBar for getting toolbar!!
// get action bar
this.getActivity().getSupportActionBar();

Dies ist sehr hilfreich, wenn Sie den Spinner in der Symbolleiste verwenden und den Spinner oder benutzerdefinierte Ansichten in der Symbolleiste von einem Fragment aus aufrufen !

Aus Ihrer Tätigkeit:

// get toolbar
this.getToolbar();
// get Action Bar
this.getSupportActionBar();
LOG_TAG
quelle
3
Sie müssen in Ihrer Aktivität eine Methode namens getToolbar () haben , was schlecht ist, da auf diese Weise nicht die Kommunikation zwischen Aktivität und Fragment erfolgen sollte.
Marko
2
Ja, dafür gibt es keinen anderen Weg !! Viele der Navigations-Schubladen-Bibliotheken implementieren nur diesen Stil !!! Manchmal müssen wir die Aktivität wegen AppCompatActivity (AppCompatActivity) getActivity () umwandeln, was ein weiterer Schmerzpunkt ist !!! all diese Sachen töten die
Entwicklungszeit
1

In XML

 <androidx.appcompat.widget.Toolbar
  android:id="@+id/main_toolbar"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  app:layout_scrollFlags="scroll|enterAlways">
 </androidx.appcompat.widget.Toolbar>

Kotlin: In fragment.kt -> onCreateView ()

setHasOptionsMenu(true)

val toolbar = view.findViewById<Toolbar>(R.id.main_toolbar)

(activity as? AppCompatActivity)?.setSupportActionBar(toolbar)

(activity as? AppCompatActivity)?.supportActionBar?.show()

-> onCreateOptionsMenu ()

   override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
       inflater.inflate(R.menu.app_main_menu,menu)
       super.onCreateOptionsMenu(menu, inflater)
   }

-> onOptionsItemSelected ()

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
             R.id.selected_id->{//to_do}
             else -> super.onOptionsItemSelected(item)
        }
    }
Priom Khan
quelle
0

Ich habe es mit diesen Schritten gemacht.

  1. Stellen Sie den Titel mit dem folgenden Code im onCreateViewHauptfragment ein.
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Your title");
  1. Zum Wechseln zwischen Fragmenten verwende ich die untere Navigationsleiste, die in MainActivity(Parent Activity) des Fragments implementiert ist . Selbst wenn Sie eine Schaltfläche oder einen Menüpunkt verwenden, können Sie den Titel von ändern onSelectedItemClickListener, genau wie in meinem Fall.
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        switch (menuItem.getItemId()){
            case R.id.menu_dashboard:
                getSupportActionBar().setTitle("Dashboard");
                fm.beginTransaction().hide(active).show(dashboardFragment).commit();
                active = dashboardFragment;
                return true;
            case R.id.menu_workshop:
                getSupportActionBar().setTitle("Workshops");
                fm.beginTransaction().hide(active).show(workshopFragment).commit();
                active = workshopFragment;
                return true;
         }
         return false;
    }
Deepak Kaushik
quelle
0

Wenn Sie eine benutzerdefinierte Symbolleiste oder Aktionsleiste verwenden und eine Referenz Ihrer Symbolleiste / Aktionsleiste von Fragmenten erhalten möchten, müssen Sie zuerst die Instanz Ihrer Hauptaktivität von der onCreateView- Methode von Fragment wie unten abrufen .

MainActivity activity = (MainActivity) getActivity();

Verwenden Sie dann die Aktivität für die weitere Implementierung wie unten

ImageView vRightBtn = activity.toolbar.findViewById(R.id.toolbar_right_btn);

Bevor Sie dies aufrufen, müssen Sie Ihre benutzerdefinierte Symbolleiste in Ihrer MainActivity wie folgt initialisieren.

Definieren Sie zunächst Ihre öffentliche Symbolleiste wie

public Toolbar toolbar;
public ActionBar actionBar;

und weisen Sie in der onCreate () -Methode die benutzerdefinierte Symbolleisten-ID zu

toolbar = findViewById(R.id.custom_toolbar);
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();

Das ist es. Es wird in Fragment funktionieren.

mdubey
quelle