FrameLayout с двумя включениями правильно устанавливает только первый.Зачем? - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть макет ScollView с FrameLayout, который включает в себя два разных макета. Если какое-то условие выполнено, я устанавливаю одно или другое как видимое. dialog_interface_login.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:font="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_white"
android:orientation="vertical">


<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <include layout="@layout/landing_login_view"/>
    <include layout="@layout/mobile_login_view"/>
</FrameLayout>
</ScrollView>

Мой класс:

final View v = inflater.inflate(R.layout.dialog_interface_login, container, false);
    View mobileLayout = v.findViewById(R.id.mobile_root_view);
    View landingLayout = v.findViewById(R.id.landing_root_view);
    if (landingLogin) {
        mobileLayout.setVisibility(View.INVISIBLE);
        landingLayout.setVisibility(View.VISIBLE);
    } else {
        mobileLayout.setVisibility(View.VISIBLE);
        landingLayout.setVisibility(View.INVISIBLE);
    }

Внутри этих макетов, которые были установлены на включении, у меня есть еще одно включение: landing_login_view.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:font="http://schemas.android.com/apk/res-auto"
android:id="@+id/landing_root_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_white"
android:paddingLeft="@dimen/twenty_eight_dp"
android:paddingRight="@dimen/twenty_eight_dp"
android:orientation="vertical">

...

<include layout="@layout/sms_login"/>

...
</LinearLayout>

И mobile_login_view.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:font="http://schemas.android.com/apk/res-auto"
android:id="@+id/mobile_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white"
android:paddingLeft="@dimen/twenty_eight_dp"
android:paddingRight="@dimen/twenty_eight_dp"
android:orientation="vertical">

...

<include layout="@layout/sms_login"/>

</LinearLayout>

Это мой sms_login.xml:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:font="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/color_white"
android:orientation="vertical">

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="@dimen/fifty_six_dp"
    android:layout_marginBottom="@dimen/twelve_dp"
    android:background="@drawable/btn_white_enabled">

    <br.com.fs.fslogin.ui.support.views.GothamEditText
        android:id="@+id/et_phone_number"
        style="@style/AppTheme.RectangularEditText"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:digits="0123456789"
        android:gravity="center"
        android:hint="@string/hint_enter_phone"
        android:inputType="number|none"
        android:maxLength="11"
        android:textColorHint="@color/task_done_color"
        android:textSize="@dimen/sixteen_sp"
        font:name="@string/font_gotham_medium" />

</FrameLayout>

<FrameLayout
    android:id="@+id/dialog_error_phone"
    android:layout_width="match_parent"
    android:layout_height="@dimen/thirty_two_dp"
    android:layout_marginBottom="@dimen/twelve_dp"
    android:background="@drawable/bg_warning_phone"
    android:visibility="gone">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="@dimen/eight_dp"
        android:layout_marginStart="@dimen/eight_dp"
        android:contentDescription="@null"
        android:src="@drawable/ic_error_phone_red" />

    <br.com.fs.fslogin.ui.support.views.GothamTextView
        android:id="@+id/error_phone_output"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:lineSpacingExtra="@dimen/two_sp"
        android:textColor="@color/error_login_phone_color"
        android:textSize="@dimen/fourteen_sp"
        font:name="@string/font_gotham_medium" />

</FrameLayout>

<FrameLayout
    android:id="@+id/btn_sms_login"
    android:layout_width="match_parent"
    android:layout_height="@dimen/fifty_six_dp"
    android:background="@drawable/btn_login_vivo_purple">

    <br.com.fs.fslogin.ui.support.views.GothamButton
        style="@style/AppTheme.RectangularButton"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:background="@null"
        android:clickable="false"
        android:gravity="center"
        android:text="@string/btn_login"
        android:textColor="@android:color/white"
        android:textSize="@dimen/eighteen_sp"
        font:name="@string/font_gotham_bold" />
</FrameLayout>

</LinearLayout>

Программно, я установил некоторые поведения, такие как маска для поля телефона и т. Д. Но эти варианты поведения, которые программно настраиваются в sms_login.xml, будут происходить только в том случае, если макет был установлен первым в моем dialog_interface_login.xml. У меня есть тот же include, с той же информацией, но он работает только с первым, определенным в ContainerLayout. Даже событие onclick не срабатывает.

У вас есть идеи, почему? Можно ли определить два разных включения?

----- Отредактировано ----- Включая некоторые действия

v.findViewById(R.id.btn_sms_login).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (phoneWatcher.isPhoneNumberValid()) {
                String phoneNumber = etPhoneNumber.getText().toString().replaceAll("\\D+", "");
                onSuccessClick.OnSuccess(phoneNumber);
                LoginInterfaceVivoSyncDialog.this.dismiss();
            }
        }
    });

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018
  • Вы должны использовать Visibility.GONE вместо INVISIBLE
  • . Вы можете напрямую назначить идентификатор для включения блока, почему вы сделали два дополнительных макета, чтобы дать только идентификатор.
  • Я был шокирован, увидев @dimen/twelve_dp ( действительно шокирован ).Какая польза от dimens.xml, если вы пишете twelve_dp там.Вы можете напрямую написать 12dp.Он должен быть общим, как space_small или space_large или text_size_small.
  • Также удалены некоторые дополнительные макеты упаковки из вашего XML.

dialog_interface_login.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/color_white"
    android:orientation="vertical">


    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <include
            android:id="@+id/landing_root_view"
            layout="@layout/sms_login" />
        <include
            android:id="@+id/mobile_root_view"
            layout="@layout/sms_login" />

    </FrameLayout>
</ScrollView>

и

final View v = inflater.inflate(R.layout.dialog_interface_login, container, false);
    View mobileLayout = v.findViewById(R.id.mobile_root_view);
    View landingLayout = v.findViewById(R.id.landing_root_view);
    if (landingLogin) {
        mobileLayout.setVisibility(View.GONE);
        landingLayout.setVisibility(View.VISIBLE);
    } else {
        mobileLayout.setVisibility(View.VISIBLE);
        landingLayout.setVisibility(View.GONE);
    }

sms_login.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:font="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/color_white"
    android:orientation="vertical">


    <br.com.fs.fslogin.ui.support.views.GothamEditText
        android:id="@+id/et_phone_number"
        style="@style/AppTheme.RectangularEditText"
        android:layout_width="match_parent"
        android:layout_height="@dimen/fifty_six_dp"
        android:layout_gravity="center"
        android:layout_marginBottom="@dimen/twelve_dp"
        android:background="@drawable/btn_white_enabled"
        android:digits="0123456789"
        android:gravity="center"
        android:hint="@string/hint_enter_phone"
        android:inputType="number|none"
        android:maxLength="11"
        android:textColorHint="@color/task_done_color"
        android:textSize="@dimen/sixteen_sp"
        font:name="@string/font_gotham_medium" />

    <FrameLayout
        android:id="@+id/dialog_error_phone"
        android:layout_width="match_parent"
        android:layout_height="@dimen/thirty_two_dp"
        android:layout_marginBottom="@dimen/twelve_dp"
        android:background="@drawable/bg_warning_phone"
        android:visibility="gone">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="@dimen/eight_dp"
            android:layout_marginStart="@dimen/eight_dp"
            android:contentDescription="@null"
            android:src="@drawable/ic_error_phone_red" />

        <br.com.fs.fslogin.ui.support.views.GothamTextView
            android:id="@+id/error_phone_output"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:lineSpacingExtra="@dimen/two_sp"
            android:textColor="@color/error_login_phone_color"
            android:textSize="@dimen/fourteen_sp"
            font:name="@string/font_gotham_medium" />

    </FrameLayout>

    <br.com.fs.fslogin.ui.support.views.GothamButton
        android:id="@+id/btn_sms_login"
        style="@style/AppTheme.RectangularButton"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/fifty_six_dp"
        android:layout_gravity="center"
        android:background="@drawable/btn_login_vivo_purple"
        android:clickable="false"
        android:gravity="center"
        android:text="@string/btn_login"
        android:textColor="@android:color/white"
        android:textSize="@dimen/eighteen_sp"
        font:name="@string/font_gotham_bold" />

</LinearLayout>
0 голосов
/ 25 апреля 2018

У вас есть идеи, почему?

Это происходит потому, что findViewById(R.id.xyz) возвращает первое View, которое имеет запрошенный атрибут android:id="@+id/R.id.xyz".

Цитирование из документации в представлении:

Находит первое дочернее представление с заданным идентификатором, само представление, если идентификатор совпадает с getId (), или ноль, если идентификатор недействителен (<0) или в иерархии нет соответствующего представления.</p>

Чтобы получить доступ к правильному View, вам нужно использовать какое-то свойство, которое делает его уникальным.В вашем случае, например, значение R.id.et_phone_number можно найти дважды в FrameLayout.Но если вы напишите

View myView = mobileLayout.findViewById(R.id.et_phone_number);

, тогда будет только один дочерний элемент View из mobileLayout с запрошенным идентификатором.

Ваш фрагмент кода можно изменить следующим образом:

final View v = inflater.inflate(R.layout.dialog_interface_login, container, false);
    View mobileLayout = v.findViewById(R.id.mobile_root_view);
    View landingLayout = v.findViewById(R.id.landing_root_view);
    if (landingLogin) {
        mobileLayout.setVisibility(View.INVISIBLE);
        landingLayout.setVisibility(View.VISIBLE);
    } else {
        mobileLayout.setVisibility(View.VISIBLE);
        landingLayout.setVisibility(View.INVISIBLE);
    }
    setupViewGroup(mobileLayout);
    setupViewGroup(landingLayout);

Метод setupViewGroup(View layout) должен выглядеть следующим образом:

private void setupViewGroup(View layout)
{
    final EditText etPhoneNumber = layout.findViewById(R.id.et_phone_number);
    layout.findViewById(R.id.btn_sms_login).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (phoneWatcher.isPhoneNumberValid()) {
                String phoneNumber = etPhoneNumber.getText().toString().replaceAll("\\D+", "");
                // ...
            }
        }
    });
}

Позвонив по номеру findViewById() на макет , вы получите нужного ребенка View из ViewGroup с, которые были добавлены с помощью <include .../>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...