Android - Фрагменты и вкладки общения - PullRequest
0 голосов
/ 20 декабря 2018

Я довольно новичок в Android.

Это мой сценарий: у меня есть простое приложение с 3 вкладками.В каждой вкладке я хочу использовать один или несколько фрагментов.Это ситуация:

  1. Вкладка 1:
    • Фрагмент A
  2. Вкладка 2:
    • Фрагмент B
    • Фрагмент C
    • Фрагмент D
  3. Вкладка 3:
    • Фрагмент E
    • Фрагмент F

В "Tab 1" у меня нет проблем.Все работает довольно хорошо.Проблемы возникают, когда мне нужно перейти в «Tab 2» и «Tab 3».

В Таблице 2 мне нужно распространить некоторые параметры от «Фрагмента B» до «Фрагмента C» и от «Фрагмента C» до «Фрагмента D».

Тогда может случиться так, что, когда пользователь нажимает на какую-то кнопку в «Фрагменте D», я должен перейти к «Tab 3» и перенести некоторые параметры из «Фрагмента D» в «Фрагмент E».

В моей основной деятельности по обработке вкладок я использую следующие компоненты:

  • android.support.design.widget.TabLayout
  • android.support.v4.view.ViewPager
  • android.support.v4.app.FragmentStatePagerAdapter (я создал собственный класс)
  • android.support.design.widget.TabLayout.OnTabSelectedListener (я создал собственный класс)

Мое очень простое расширение FragmentStatePagerAdapter:

public class MyOwnPageAdapter extends FragmentStatePagerAdapter {
    private int numeroTab;
    public MyOwnPageAdapter(FragmentManager fm, int numeroTab) {
        super(fm);
        this.numeroTab = numeroTab;
    }
    @Override
    public Fragment getItem(int position) {
        switch (position){
            case 0:
                return new FragmentA() ;
            case 1:
                return new FragmentB() ;
            case 2:
                return new FragmentC() ;
            default:
                return null;
        }
    }
    @Override
    public int getCount() {
        return numeroTab;
    }
}

Мое очень простое расширение TabLayout.OnTabSelectedListener:

public class TabSelectedListener implements TabLayout.OnTabSelectedListener {
    private ViewPager viewPager;
    public TabSelectedListener(ViewPager viewPager){

        this.viewPager = viewPager;
    }
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
}

Я умею переключать фрагментывнутри вкладок, которые находятся на вкладке 2, я могу переключиться с фрагмента B на фрагмент C и так далее.У меня проблемы с передачей параметров между фрагментами и, прежде всего, из фрагмента D на вкладке 2 в фрагмент E на вкладке 3

В моей реализации фрагментов, используя android.support.v4.app.FragmentManager, я могу добавлять и удалять представления (например, фрагменты)), выполнив что-то вроде этого:

mFragmentManager.beginTransaction().add(rootView.getId(),mListaEdificiFragment, "BUILDS").addToBackStack(null).commit();

Проблема заключается в распространении параметра, так как FragmentStatePagerAdapter, кажется, кэширует представления, случается, что вызывается конструктор фрагмента, но onCreate и onCreateViewбольше не вызывается, поэтому я не могу обработать распространяемые параметры.

Есть ли какое-либо решение для этого?Или я просто ошибаюсь в своем шаблоне навигации?Я хотел бы избежать сворачивания фрагмента B, фрагмента C и фрагмента D в одном «большом представлении», где можно спрятать какой-то раздел (то же самое для фрагмента E и фрагмента F)

Любое предложение более чем приветствуется

Анджело

Ответы [ 4 ]

0 голосов
/ 21 декабря 2018

Наконец-то я получил решение.Поскольку основной проблемой является передача фрагментов, я следовал официальной документации

Предположим, у меня есть фрагмент A со списком статей и фрагмент B, где можно посмотреть детали выбранной статьи в моем фрагментеА я написал:

public class FragmentA extends Fragment {
    private OnArticleSelectionListener mCallback;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
        }
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.activityedifici, container, false);     
        return rootView;
    }



    public interface OnArticleSelectionListener {

        void onArticleSelection(String articleId);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mCallback = null;
    }


    public void setOnArticleSelectionListener(OnArticleSelectionListener mCallback) {
        this.mCallback = mCallback;
    }
}

Как вы можете видеть, я объявил следующий интерфейс

public interface OnArticleSelectionListener {

        void onArticleSelection(String articleId);
    }

Это слушатель выбора статьи.

В своей основной деятельности я написалследующее:

public class MainActivity implements FragmentA.OnArticleSelectionListener{
//All my own stuffs

    @Override
    public void onAttachFragment(Fragment fragment) {
        if (fragment instanceof FragmentA){
            FragmentA ef = (FragmentA)fragment;
            ef.setOnArticleSelectionListener(this);
        }
    }
    @Override
    public void onArticleSelection(String articleId) {
        if( getSupportFragmentManager().findFragmentByTag(TAG_ARTICLE_DETAIL) != null ){
        //FragmentB is the article detail and it has already been created and cached
            FragmentB dcf = (FragmentB)getSupportFragmentManager().findFragmentByTag(TAG_ARTICLE_DETAIL);
            dcf.updateArticleDetail( articleId );
        }else{
        //FragmentB is the article detail and it has never been created I create and replace the container with this new fragment
            FragmentB dcf = new FragmentB();
        //Parameter propagation
            Bundle args = new Bundle();
            args.putString(FragmentB.ARG_ARTICLE_ID, articleId);
            dcf.setArguments(args);
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.container_articles, dcf, TAG_ARTICLE_DETAIL);
            transaction.addToBackStack(null);
            transaction.commit();
        }
    }
}

Таким образом, я могу перехватывать события во FragmentA и распространять их во FragmentB;когда мне нужно открыть вкладку, все остается прежним и, наконец, (после transaction.commit() или dcf.updateArticleDetail( articleId )) я делаю следующее tabLayout.getTabAt(2).select();, и открывается третья вкладка (индекс вкладки начинается с 0), и отображается деталь.

Надеюсь, это может быть полезно

Анджело

0 голосов
/ 20 декабря 2018

Я пишу свой Fragment таким образом, чтобы передать ему данные.

public class MyFragment extends Fragment {
    private static String ARG_PARAM1 = "data";
    private String data;

    public MyFragment() {
        // Required empty public constructor
    }

    public static MyFragment newInstance(String data) {
        MyFragment fragment = new MyFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, data);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            data = getArguments().getString(ARG_PARAM1);
        }
    }
}

Теперь данные можно передавать на Fragment, вызывая MyFragment.newInstance("Hello").Надеюсь, это поможет.

0 голосов
/ 20 декабря 2018

Я столкнулся с подобной проблемой в моем проекте.В моем случае у меня есть viewpager, и у каждой вкладки есть несколько фрагментов.

Поэтому одно из простых решений - использовать LiveData и ViewModel .

* 1008.* В вашей Tab2:

Фрагмент B

Фрагмент C

Фрагмент D

TabTwoViewModel (с живыми данными)

В обозревателе изменяемых живых данных эти оперативные данные передаются во фрагменты B, C и D.

Когда вы обновляете объект живых данных, живые данные автоматически уведомляют весь фрагмент.

0 голосов
/ 20 декабря 2018

Одним из простых решений для передачи значения переменной из одного фрагмента в другой является использование общих настроек (также может использоваться для передачи значений из одного действия в другое).Общее предпочтение сохранит данные против переменных, которые будут сохраняться во всех действиях и фрагментах в приложении для Android.

Теперь в вашем случае давайте предположим, что вы хотите передать значение name = angelo из фрагмента A во фрагмент B.В своем фрагменте A напишите этот код:

 Button updateName = findViewById(R.id.btnupdateTeamName);
 updateTeamName .setOnClickListener(new View.OnClickListener() {
 @Override
    public void onClick(View v) {
        SharedPreferences.Editor editor = sharedpreferences.edit();
        editor.putString("name", "angelo");
        editor.commit();
    }
 });

При выполнении вышеприведенный код обновит значение name с angelo в общих настройках.Это будет доступно в вашем приложении.

Для получения дополнительной информации об общих настройках, ознакомьтесь с официальным документом .

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