FragmentPagerAdapter передает список объектов фрагменту, когда данные готовы - PullRequest
0 голосов
/ 26 апреля 2018

Я создал приложение, используя FragmentPagerAdapter с внутренним статическим классом из 3 фрагментов, скажем, MainActivity. В основном, шаблон андроид-студии с вкладками генерирует код таким же образом, также в документации Android используется этот внутренний статический класс, например. создание вида смахивания

Но это будет плохо для производительности, потому что я должен заставить все переменные и функции стать статичными, чтобы это работало, и это тоже не то, что нужно делать.

Поэтому я пытаюсь разделить фрагмент на его собственный класс, и из этой статьи связь между фрагментом он говорит нам, как отправить переменную / действие обратного вызова от фрагмента к родительской активности (в моем случае это MainActivity)

И после некоторого исследования отправка данных из активности во фрагмент также может быть выполнена с использованием интерфейса. Но становится как реализуем друг друга и я получаю

ошибка циклического наследования

Большинство тем в Интернете, где обсуждаются способы передачи данных из действия во фрагмент, возникает при создании фрагмента, использовании пакета и т. Д.

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

Есть ли какой-нибудь правильный способ передачи данных (в моем случае List Object) от действия к фрагменту в определенное время, когда запрос к серверу завершен (фрагмент уже создан ранее)? Спасибо ,

Вот мой код

MainActivity

    public class MainActivity extends AppCompatActivity implements BlankFragment.OnFragmentInteractionListener {

    //On create
    ViewPager viewPager = findViewById(R.id.vpPager);
    MyPagerAdapter adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(adapterViewPager);


    //adapter
    public static class MyPagerAdapter extends FragmentPagerAdapter {
    private static int NUM_ITEMS = 3;
    private String tabTitles[] = new String[]{"Home", "History", "My Account"}; 

    public MyPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    // Returns total number of pages
    @Override
    public int getCount() {
        return NUM_ITEMS;
    }

    // Returns the fragment to display for that page
    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return BlankFragment.newInstance();
            case 1:
                return FragmentHistory.newInstance();
            case 2:
                return FragmentAccount.newInstance();
            default:
                return BlankFragment.newInstance();
        }
    }

    // Returns the page title for the top indicator
    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles[position];
    }

}
 @Override
public void onFragmentInteraction() {
    getKegiatan();
}
}

BlankFragment

public class BlankFragment extends Fragment {

private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;

private OnFragmentInteractionListener mListener;


private final Context context = getContext();
private SharedPreferences sharedPreferences;
private int mRole;


private ImageView ivNoData;
private ExpandableListView elvKegiatan;
private ListView lvKegiatan;

private EditText etFrom, etTo;
private String dateFrom, dateTo;

private List<Kegiatan> listKegiatan;
private List<Kegiatan> superKegiatanSaya;
private List<Kegiatan> superKegiatanAnak;



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

public static BlankFragment newInstance() { //String param1, String param2
    BlankFragment fragment = new BlankFragment();
    return fragment;
}

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

        sharedPreferences = context.getSharedPreferences(
                getResources().getString(R.string.myspkey), Context.MODE_PRIVATE);

        mRole = sharedPreferences.getInt(getString(R.string.splogin_role), 0);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_kegiatan, container, false);


    FloatingActionButton fabAddKeg = view.findViewById(R.id.fabAddKegiatan);
    fabAddKeg.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(context, TambahKegiatanActivity.class));
        }
    });


    lvKegiatan = view.findViewById(R.id.listViewKegiatan);
    elvKegiatan = view.findViewById(R.id.elvKegiatan);

    View buttonSearch = view.findViewById(R.id.buttonSearch);
    buttonSearch.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onButtonPressed();
        }
    });


    etFrom = view.findViewById(R.id.editTextFrom);
    etTo = view.findViewById(R.id.editTextTo);

    populateList();
    prepareDate();


    LinearLayout llRangeKeg = view.findViewById(R.id.linearLayoutRangeKeg);
    switch (mRole){
        case UserConst.ROLE_USER:
            break;
        case UserConst.ROLE_SUPER:
        case UserConst.ROLE_CEO:
        case UserConst.ROLE_CFO:
            llRangeKeg.setVisibility(View.GONE);
            break;
        case UserConst.ROLE_ADMIN:
        case UserConst.ROLE_FINANCE:
            llRangeKeg.setVisibility(View.GONE);
            fabAddKeg.setVisibility(View.GONE);
            break;
    }

    return view;

}


// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed() {
    if (mListener != null) {
        mListener.onFragmentInteraction();
    }
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

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


/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p>
 * See the Android Training lesson <a href=
 * "http://developer.android.com/training/basics/fragments/communicating.html"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction();

}

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Я думаю, что вы можете использовать EventBus для этой ситуации

  1. Создать класс для события (для примера данных)

    открытый класс Data { публичный список объектов; // getter & setter }

  2. В свой Фрагмент положи подписчика. Добавить:

    @ Subscribe (threadMode = ThreadMode.MAIN)
    public void onMessageEvent (Данные данных) { // Вы можете получить список объектов с помощью data.getObjects ();
    };

  3. Зарегистрируйте и отмените регистрацию вашего подписчика (во фрагменте)

    @ Override public void onStart () { super.onStart (); . EventBus.getDefault () регистр (это); } * * Тысяча двадцать-один

    @ Override public void onStop () { super.onStop (); . EventBus.getDefault () разрегистрировать (это); }

  4. В вашей активности опубликовать событие, когда данные будут готовы

    Данные данные = новые данные (); data.setObject (объекты); EventBus.getDefault () сообщение (данные).

  5. Не забудьте добавить зависимости от классов:

    реализация 'org.greenrobot: eventbus: 3.1.1'

Подробнее здесь

0 голосов
/ 26 апреля 2018

1) Определить интерфейс слушателя. Я обычно делаю это как внутренний интерфейс в деятельности:

 public interface DataUpdateListener {
        void onDataUpdate(List<Object> mData);
    }

2) сделать объект интерфейса

DataUpdateListener dataListener;

3) Добавьте методы регистрации в действие:

public void registerDataUpdateListener(DataUpdateListener listener) {
     dataListener=listener;
}

4) Пусть ваши фрагменты реализуют DataUpdateListener:

 public class MyFragment extends Fragment implements DataUpdateListener {

5) реализовать метод

 @Override
    public void onDataUpdate(List<Object> mData) {
        // put your UI update logic here
    }

6) Переопределить onAttach () и onDestroy () во фрагментах для регистрации / отмены регистрации:

 @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        ((MainActivity) activity).registerDataUpdateListener(this);
    }

7) При обновлении пользовательского интерфейса во фрагменте

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