it-swarm.com.de

Wie erhalte ich eine Ansicht vom Schubladenkopflayout mit Bindungsaktivität?

Das ist also meine activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout 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"
        tools:context="MainActivity"
    >
    <!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
    <Android.support.v4.widget.DrawerLayout
        Android:id="@+id/drawer_layout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        >

        <!-- As the main content view, the view below consumes the entire
             space available using match_parent in both dimensions. -->

        <RelativeLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent">

            <LinearLayout
                Android:id="@+id/ll_container"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:orientation="vertical">

                <Android.support.v7.widget.Toolbar
                    Android:id="@+id/my_awesome_toolbar"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:background="@Android:color/black"
                    Android:fitsSystemWindows="true"
                    >

                    <TextView
                        Android:id="@+id/toolbar_title"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:layout_marginLeft="10dp"
                        Android:layout_marginStart="10dp"
                        Android:textColor="@Android:color/white"
                        Android:textSize="@dimen/abc_text_size_title_material_toolbar"
                        tools:text="@string/default_toolbar_title"/>

                </Android.support.v7.widget.Toolbar>


                <FrameLayout
                    Android:id="@+id/container"
                    Android:layout_width="match_parent"
                    Android:layout_height="match_parent">

                </FrameLayout>
            </LinearLayout>

            <Android.support.design.widget.FloatingActionButton
                Android:id="@+id/fab_fuf"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_alignParentBottom="true"
                Android:layout_alignParentEnd="true"
                Android:layout_alignParentRight="true"
                Android:layout_marginBottom="20dp"
                Android:layout_marginEnd="20dp"
                Android:layout_marginRight="20dp"
                Android:src="@drawable/flamme"
                app:fabSize="normal"
                />
        </RelativeLayout>

        <Android.support.design.widget.NavigationView
            Android:id="@+id/navigation_view"
            Android:layout_width="wrap_content"
            Android:layout_height="match_parent"
            Android:layout_gravity="start"
            Android:background="@Android:color/black"
            **app:headerLayout="@layout/drawer_header"**
            app:itemTextColor="@color/drawer_item_color_selector"
            app:menu="@menu/menu_drawer"/>

    </Android.support.v4.widget.DrawerLayout>
</layout>

und ich verwende die Bindung für die Aktivität, so dass ich die findViewById nicht verwenden und sie usw. so umwandeln muss: 

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        Toolbar toolbar = binding.myAwesomeToolbar;
        toolbarTitle = binding.toolbarTitle;
        BalrogFontsHelper.SetKhandBoldToView(toolbarTitle);
        setSupportActionBar(toolbar);
        final ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setHomeAsUpIndicator(R.drawable.ic_dehaze_white_24);
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            actionBar.setDisplayShowTitleEnabled(false);
        }


        drawerLayout = binding.drawerLayout;
        **tvLoggedUserEmail = (TextView) findViewById(R.id.tv_logged_user_email);**
        BalrogFontsHelper.SetKhandBoldToView(tvLoggedUserEmail);

Wie Sie sehen, kann ich die Ansichten, die direkt im Layout von activity_main.xml enthalten sind, durch Binden abrufen, aber wenn die angezeigte Ansicht nicht angezeigt wird, kann ich die Variable nicht im Bindungsobjekt sehen.

drawer_header.xml:

    <?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="96dp"
                xmlns:tools="http://schemas.Android.com/tools"
                Android:background="@Android:color/black"
                Android:theme="@style/ThemeOverlay.AppCompat.Dark">


    <TextView
        Android:id="@+id/tv_logged_user_email"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_centerVertical="true"
        Android:layout_marginLeft="16dp"
        tools:text="@string/login_placeholder_email"
        Android:textAllCaps="true"
        Android:textAppearance="@style/TextAppearance.AppCompat.Body2"
        Android:textSize="20sp"/>


</RelativeLayout>

Wie konnte ich diese tv_logged_user_email TextView verbindlich erhalten, so habe ich:

**tvLoggedUserEmail = binding.tvLoggedUserEmail;**
27
RogerParis

Aktualisierte Lösung (13.11.2015)

Lösung: Aktualisieren Sie Ihre Design Support Library auf 23.1.1:

Änderungen für die Design Support-Bibliothek 23.1.1:

  • Die getHeaderView-Methode wurde der NavigationView-Klasse hinzugefügt.
  • Problem mit transparentem Hintergrund für ein FloatingActionButton-Objekt auf Geräten mit Android 4.0 (API-Ebene 15) und niedriger wurde behoben. (Ausgabe 183315)

Siehe https://developer.Android.com/tools/support-library/index.html für weitere Informationen


Originallösung

Ich weiß nicht, warum es keine Methode gibt, die die programmgesteuert angehängte Header-Ansicht

Hier sind zwei Lösungen:

NavigationView navigationView = (NavigationView) findViewById(R.id.navigation);
View headerView = navigationView.inflateHeaderView(R.layout.header_layout)
ImageView iv = (ImageView)headerview.findViewById(R.id.your_image_view)

Oder:

NavigationView navigationView = (NavigationView) findViewById(R.id.navigation);
View headerView = LayoutInflater.from(this).inflate(R.layout.header_layout, navigationView, false);
navigationView.addHeaderView(headerView);

ImageView iv = (ImageView) headerView.findViewById(R.id.yourImageView)
32
leejaycoke

Ich habe eine etwas sauberere Lösung, bei der ich Fragment/Aktivität nicht mit Code "verschmutzen" muss, der für das Aufblasen und das Hinzufügen von Header-Ansichten zu NavigationView verantwortlich ist. Ich habe Erweiterungsklasse für NavigationView implementiert. Ich habe das so gemacht:

Aufbau meiner Tätigkeit:

<data>
    <variable
        name="dashboard"
        type="ramps.view.model.DashboardScreenViewModel"/>
</data>

<Android.support.v4.widget.DrawerLayout
    Android:id="@+id/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/activity_dashboard"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        bind:dashboard="@{dashboard}"
        />

    <Android.support.design.widget.NavigationView
        Android:id="@+id/nav_view"
        Android:background="@color/white"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:fitsSystemWindows="true"
        app:navigationItemSelectedListener="@{dashboard.onMenuItemSelected}"
        app:model="@{dashboard.score}"
        app:menu="@menu/activity_main_drawer"/>

</Android.support.v4.widget.DrawerLayout>

Wie Sie sehen, gibt es keine App: headerLayout in NavigationView, aber ich habe mein benutzerdefiniertes App: model hinzugefügt, mit Daten, die ich an das Header-Layout übergeben möchte. Wie definiere ich diesen benutzerdefinierten Parameter? Nach Erweiterungsklasse:

public class NavigationViewExtensions {

@BindingAdapter({"bind:model"})
public static void loadHeader(NavigationView view, ScoreViewModel model) {
    ViewNavigationHeaderBinding binding = ViewNavigationHeaderBinding.inflate(LayoutInflater.from(view.getContext()));
    binding.setScore(model);
    binding.executePendingBindings();
    view.addHeaderView(binding.getRoot());
  }
}

Platzieren Sie diese Klasse einfach irgendwo in Ihrem Projekt. Und das Layout meines Headers:

<layout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:bind="http://schemas.Android.com/apk/res-auto"
>

<data>

    <import type="Android.view.View"/>

    <variable
        name="score"
        type="ramps.view.model.ScoreViewModel"/>
</data>

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@color/graphite"
    Android:gravity="bottom"
    Android:orientation="vertical"
    Android:paddingBottom="@dimen/activity_vertical_margin_large"
    Android:paddingLeft="@dimen/activity_horizontal_margin"
    Android:paddingRight="@dimen/activity_horizontal_margin"
    Android:paddingTop="@dimen/activity_vertical_margin_large"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <include
        Android:id="@+id/player_details_header_score"
        layout="@layout/view_avatar_score_header"
        bind:score="@{score}"/>

</LinearLayout>

14
Ramps

Ich hatte/hatte das gleiche Problem.

Eine Problemumgehung besteht darin, die Kopfansicht zu vergrößern und sie programmgesteuert hinzuzufügen.

So was:

DrawerHeaderBinding drawerHeaderBinding = DrawerHeaderBinding.inflate(LayoutInflater.from(navigationView.getContext()));
navigationView.addHeaderView(drawerHeaderBinding.getRoot());
drawerHeaderBinding.tvLoggedUserEmail = "email";
drawerHeaderBinding.executePendingBindings();

Entfernen Sie also die App: headerLayout und führen Sie sie programmgesteuert aus. Ich denke jedoch, Google sollte das Kernproblem hier beheben, entweder in der Designbibliothek oder in der Datenbindungsbibliothek.

10
Tosa

Wenn Sie app:headerLayout="@layout/drawer_header einstellen, müssen Sie die Ansicht nicht erneut aufblasen. Sie können einfach .bind anstelle von .inflate verwenden. 

Sie können die bereits aufgeblähte Kopfansicht aufrufen und wie folgt binden:

View headerView = binding.navigationView.getHeaderView(0);
DrawerHeaderBinding headerBinding = DrawerHeaderBinding.bind(headerView);
8
stefana
ImageView imageView = (ImageView) navigationView.getHeaderView(0).findViewById(R.id.imageButton);

imageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        if (flag) {
            navigationView.getMenu().clear(); //clear old inflated items.
            navigationView.inflateMenu(R.menu.drawer_view1);
            flag = false;
        } else {
            navigationView.getMenu().clear(); //clear old inflated items.
            navigationView.inflateMenu(R.menu.drawer_view);
            flag = true;
        }
    }
});
8
user5783673

Eine ganz einfache Lösung hier. Nehmen wir an, Sie haben Ihre Navigationsansicht als hinzugefügt

<Android.support.design.widget.NavigationView
    Android:id="@+id/navigationView"
    Android:layout_width="wrap_content"
    Android:layout_height="match_parent"
    Android:layout_gravity="start"
    Android:fitsSystemWindows="true"
    app:headerLayout="@layout/my_nav_drawer_header"
    app:menu="@menu/menu_nav_drawer"/>

Und Sie möchten auf eine TextView in my_nav_drawer_header.xml zugreifen, die die ID textView2 hat. Sie würden diesen Code also einfach in Ihrer Aktivität verwenden:

View headerContainer = navigationView.getHeaderView(0); // This returns the container layout from your navigation drawer header layout file (e.g., the parent RelativeLayout/LinearLayout in your my_nav_drawer_header.xml file)
TextView textView2 = (TextView)headerContainer.findViewById(R.id.textView2);
textView2.setText("Sorted!");

Keine Notwendigkeit, den vorhandenen Code usw. aufzublasen oder zu beeinträchtigen.

4

Versuchen Sie dies mit der DataBinding-Bibliothek, die für mich funktioniert.

navigation_view_header.xml:

<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
<RelativeLayout
    Android:layout_width="match_parent"
    Android:layout_height="@dimen/navigation_view_header_height"
    Android:paddingLeft="@dimen/navigation_view_padding"
    Android:paddingTop="@dimen/navigation_view_top_padding"
    Android:background="@color/colorPrimary">


    <ImageView
        Android:id="@+id/avatar"
        Android:layout_width="@dimen/avatar_dimen"
        Android:layout_height="@dimen/avatar_dimen"
        Android:contentDescription="@null"
        Android:src="@drawable/default_avatar" />

    <TextView
        Android:id="@+id/profile_email"
        Android:layout_width="match_parent"
        Android:layout_height="48dp"
        Android:layout_below="@+id/avatar"
        Android:text="email"
        Android:textColor="@color/white"
        Android:layout_alignParentBottom="true"
        Android:gravity="center_vertical" />

</RelativeLayout>
</layout>

activity_main.xml:

<layout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">
    <data>
        <variable
            name="navigationItemSelectedListener"
            type="com.example.MainActivity"/>
    </data>
<Android.support.v4.widget.DrawerLayout
    Android:id="@+id/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true"
    Android:tag="layout">

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:orientation="vertical">

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/my_toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            app:titleTextColor="@color/white"
            Android:background="@color/colorPrimary"
            app:theme="@style/Toolbar.Theme"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

        <FrameLayout
            Android:id="@+id/fragment_container"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent" />
    </LinearLayout>

    <Android.support.design.widget.NavigationView
        Android:id="@+id/navigation_view"
        Android:layout_width="@dimen/navigation_view_width"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:fitsSystemWindows="true"
        app:theme="@style/Theme.AppCompat.Light"
        app:menu="@menu/drawer_menu"
        app:navigationItemSelectedListener="@{navigationItemSelectedListener::onNavigationItemSelected}"/>

</Android.support.v4.widget.DrawerLayout>
</layout>

und innerhalb Ihrer Aktivität:

ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,
                R.layout.activity_main);
activityMainBinding.setNavigationItemSelectedListener(this);/* with this line navigation menu item selection events are handled in onNavigationItemSelected() specified in navigation_view_header.xml*/

NavigationViewHeaderBinding navigationViewHeaderBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.navigation_view_header,activityMainBinding.navigationView,false);
        activityMainBinding.navigationView.addHeaderView(navigationViewHeaderBinding.getRoot());

und stellen Sie sicher, dass Ihre Aktivität NavigationView.OnNavigationItemSelectedListener implementiert.

1
Yasser Khayyal
  • Bearbeiten Sie Ihre Gradle-Datei, um com.Android.support -Bibliotheken auf Version 23.1.1 oder höher zu aktualisieren.

  • Verwenden Sie navigationView.getHeaderView(i), wobei i der Index der headerview ist. Wenn Sie diese Ansicht gerade im Layout definiert haben, lautet 0

0
Renascienza

Fügen Sie einfach navigationView.getHeaderView (0) ein und verwenden Sie dann beliebige Ansichten

        TextView profile,info;
        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        profile = navigationView.getHeaderView(0).findViewById(R.id.profile);
        info = navigationView.getHeaderView(0).findViewById(R.id.info);
        profile.setOnClickListener(this);
        info.setOnClickListener(this);
0
milan pithadia

Ich habe Build-Tools von Android SDK-Manager aktualisiert, dann funktioniert 23.1.0 auch für mich.

Ich benutze buildToolsVersion "23.0.2" Vorher war es 23.0.1.

und es besteht keine Notwendigkeit zu verwenden:

(View) navigationView.findViewById(R.id.idOfViewFromHeaderView);

In Ihrer Aktivität können Sie direkt verwenden:

(View) findViewById(R.id.idOfViewFromHeaderView);
0
Muhammad Adil