Если я объявляю фрагмент в расположении XML, как я передаю его Пакет?

У меня есть действие, которое я заменил фрагментом. Действие взяло Намерение, которое имело некоторую дополнительную информацию о том, какие данные действие, как предполагалось, отобразило.

Теперь, когда мое Действие является просто оберткой вокруг Фрагмента, который делает ту же работу, как я получаю тот пакет к Фрагменту, если я объявляю фрагмент в XML с тегом?

Если бы я должен был использовать FragmentTransaction для помещения Фрагмента в ViewGroup, то я получил бы шанс провести эту информацию в конструкторе Fragment, но я задаюсь вопросом о ситуации, где фрагмент определяется в XML.

62
задан 23 October 2012 в 20:07

3 ответа

Вы не можете передать Пакет (если Вы не расширяете свой фрагмент программно скорее затем через XML), но Вы параметры передачи CAN (или скорее приписывает) через XML к фрагменту.

процесс подобен , как Вы определяете пользовательские атрибуты Представления . Кроме AndroidStudio (в настоящее время) не помогают Вам в процессе.

предполагают, что это - Ваш фрагмент с помощью аргументов (я буду использовать kotlin, но он полностью работает в Java также):

class MyFragment: Fragment() {

    // your fragment parameter, a string
    private var screenName: String? = null

    override fun onAttach(context: Context?) {
        super.onAttach(context)
        if (screenName == null) {
            screenName = arguments?.getString("screen_name")
        }
    }
}

И Вы хотите сделать что-то вроде этого:

<fragment
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/myFragment"
    android:name="com.example.MyFragment"
    app:screen_name="@string/screen_a"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

Примечание app:screen_name="@string/screen_a"

, чтобы заставить это работать просто добавляет это в файле значений (fragment_attrs.xml, или выберите любое имя, которое Вы хотите):

<!-- define your attribute name and type -->
<attr name="screen_name" format="string|reference"/>

<!-- define a bunch of constants you wanna use -->
<string name="screen_a" translatable="false">ScreenA</string>
<string name="screen_b" translatable="false">ScreeenB</string>

<!-- now define which arguments your fragment is gonna have (can be more then one) -->
<!-- the convention is "FragmentClassName_MembersInjector" -->
<declare-styleable name="MyFragment_MembersInjector">
    <attr name="screen_name"/>
</declare-styleable>

Почти сделанный, просто необходимо считать его во фрагменте, поэтому добавьте метод:

override fun onInflate(context: Context?, attrs: AttributeSet?, savedInstanceState: Bundle?) {
    super.onInflate(context, attrs, savedInstanceState)
    if (context != null && attrs != null && screenName == null) {
        val ta = context.obtainStyledAttributes(attrs, R.styleable.MyFragment_MembersInjector)
        if (ta.hasValue(R.styleable.MyFragment_MembersInjector_screen_name)) {
            screenName = ta.getString(R.styleable.MyFragment_MembersInjector_screen_name)
        }
        ta.recycle()
    }
}

и voilГЎ, Ваши атрибуты XML в Вашем фрагменте :)

Ограничения:

  • Studio Android (на данный момент) не автоматически заполняет такие аргументы в расположении XML
  • , Вы не можете передать Parcelable, но только что может быть определено как Атрибуты Android
8
ответ дан 31 October 2019 в 14:03

Другая опция не состоит в том, чтобы объявить фрагмент в XML. Я знаю, что это не точно, что Вы хотите сделать. Однако Вы могли объявить простой макет в своем представлении как это:

    <LinearLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

И затем в Вашем Activity классифицируют Вас, программно расширяют расположение с фрагментом. Таким образом, можно пройти через параметры с помощью args.

 FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    MyFragment fragment = MyFragment.newInstance();
    Bundle args = new Bundle();
    args.putInt(Global.INTENT_INT_ROLE, 1);
    fragment.setArguments(args);
    fragmentTransaction.add(R.id.fragment_container, fragment, "MyActivity");
    fragmentTransaction.commit();

Этот подход не является столь же чистым и простым как объявление его в xml однако, я переместился в него, поскольку это дает Вам намного больше контроля фрагментом.

9
ответ дан 31 October 2019 в 14:03

Это не инкапсулированный путь, но я закончил тем, что "вытянул" пакет от родительского действия:

Bundle bundle = getActivity().getIntent().getExtras();
43
ответ дан 31 October 2019 в 14:03

Другие вопросы по тегам:

Похожие вопросы: