Подтвердить что ты не робот

Активность ViewPager для уведомления фрагмента определенного события

У меня есть ViewPager, и он использует FragmentAdapter для отображения нескольких фрагментов одного и того же типа. Хотя эти фрагменты в основном создаются из одного класса, они используют ListView для отображения различной информации. (Очевидно, что ListView poulated на ArrayAdapter.)
Фоновая служба также работает и постоянно получает данные из Интернета. Я хочу иметь возможность обновлять определенный фрагмент в ViewPager, когда мой фоновый сервис уведомил меня о конкретном событии.
Как я могу это сделать? Фрагмент кода был бы очень оценен!

(Кстати, я видел этот похожий вопрос, но я не знаю, как использовать их предложение!)

Сделать все проще: Моя активность с ViewPager:
[Фрагмент 0] [Фрагмент 1] [Фрагмент 2]

Фоновая служба сообщает мне (через трансляцию) обновить ListView в Фрагмент 1.

EDIT: Вот примеры кода:

public class ChatWindowPager extends FragmentActivity
{
    private ViewPager mViewPager = null;
    private ChatFragmentAdapter mAdapter = null;
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chat_window_pager);

        this.mViewPager = (ViewPager) findViewById(R.id.chatPager);
        this.mAdapter = new ChatFragmentAdapter(getSupportFragmentManager());
        this.mViewPager.setAdapter(this.mAdapter);
        .
        .
        .
    }

    class ChatFragmentAdapter extends FragmentPagerAdapter implements ViewProvider
    {

        public ChatFragmentAdapter(final FragmentManager fm)
        {
            super(fm);
        }

        @Override
        public Fragment getItem(final int arg0)
        {
            String friendId = ..... // Some initializations
            ChatWindowFragment f = ChatWindowFragment.newInstance(friendId);
            return f;
        }

        @Override
        public int getCount()
        {
            ...
        }

        @Override
        public View getView(final int position)
        {
            View v = getLayoutInflater().inflate(R.layout.tab_holder, null);
            .
            .
            .
            return v;
        }
    }
}

Теперь фрагменты определяются следующим образом:

public class ChatWindowFragment extends Fragment
{
    public String friendId;
    private ListView lv;

    public static ChatWindowFragment newInstance(final String friendId)
    {
        ChatWindowFragment chatWindowFragment = new ChatWindowFragment();
        Bundle bundle = new Bundle();
        bundle.putString("friendId", friendId);
        chatWindowFragment.setArguments(bundle);
        return chatWindowFragment;
    }

    @Override
    public void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        this.friendId = getArguments().getString("friendId");
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
    {
        View v = inflater.inflate(R.layout.chat_window, container, false);

        this.friendId = getArguments().getString("friendId");
        .
        .
        .
        return v;
    }

    //The rest of the class

}

Как я использую FragmentPagerAdapter, я не вижу, как я могу установить тег каждого фрагмента! (Очевидно, что я не использую транзакции для добавления фрагментов!)

ИЗМЕНИТЬ 2: Я хотел бы знать, что я делаю, это правильный способ справиться с тем, что я хочу... Любое другое решение также приветствуется!

4b9b3361

Ответ 1

Попробуйте это,

Зарегистрируйте широковещательный приемник во всех ваших фрагментах... например

создать класс, который расширяет широковещательный приемник во всех классах, например:

public class FragmentReceiver1 extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
        }    
}

и зарегистрируйте этот ресивер в вашем фрагменте onCreate...

например. getActivity().registerReceiver(new FragmentReceiver1(), new IntentFilter("fragmentupdater"));

Теперь назначьте уникальный идентификатор для каждого из фрагментов, например 1 для Fragment1, 2 для Fragment2 и аналогично

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

Например,

Intent data = new Intent("fragmentupdater");
data.putString("key","data");
data.putInt("fragmentno",1); // Pass the unique id of fragment we talked abt earlier
activity.sendBroadcast(data);

Теперь каждый ваш фрагмент получит данные, но вы можете проверить, являются ли данные, если для одного и того же фрагмента уникальным идентификатором, который мы передали в нем в функции onReceive..., целью, которое вы получаете, является мы прошли выше

Ответ 2

Вы пробовали FragmentManager.findFragmentByTag()

FragmentManager manager = getSupportedFragmentManager();
//with support package, else
//FragmentManager manager = getFragmentManager()
Fragment fragment = manager.findFragmentByTag("Tag You Created the Fragment");
if (fragment instanceof Fragment1){
    Fragment1 fr = (Fragment1)fragment
    fr.updateData(DATA)
    //or any method of your choice
} 

EDIT: Я внимательно прочитал! instanceOf будет отбрасывать Fragment в ваш класс фрагментов. Это вы, который предложил Fragment1 как имя для простоты. Кроме того, вы не предоставили никаких источников, чтобы помочь нам. Это правда, что вы не можете установить тег Fragment, но почему, по-вашему, вы можете получить его тег? Обычно Fragment добавляется через FragmentManagers, например

FragmentManager manager = getSupportedFragmnentManager()
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(int containerViewId, Fragment fragment, String tag);
// or transaction.add(Fragment fragment, String tag)
// ...other transactions
transaction.commit()

EDIT2: это очень легко. в соответствии с вашим кодом вы можете просто позвонить

Fragment fragment = mAdapter.getItem(0) // 0||1||2

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

Ответ 3

У меня была такая же проблема, но она была исправлена ​​с localBroadcastReceiver следующим образом:

Создайте ресивер в своей деятельности и зарегистрируйте его:

 /**
 * ******************************
 * Receiver to process the message
 * *******************************
 */
private BroadcastReceiver onNotice = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        //You can send any extra data if you need like this
        final int type = intent.getIntExtra("fragment.data", -1);
        Log.d(tag, "main class: " + type);
        //also refresh your fragment like this
        mViewPager.getViewPager().getAdapter().notifyDataSetChanged();
    }
};    

@Override
protected void onResume() {
    super.onResume();

    //Register a localbroadCast with the your filter
    IntentFilter thinaireFilter = new IntentFilter("your.filter");
    LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, thinaireFilter);
}

Не забудьте удалить LocalBroadCast

//remove the LocalBroadCast when no need it
@Override
protected void onPause() {
    super.onPause();
    LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
}
@Override
protected void onDestroy() {
    super.onDestroy();
    LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
}

Отправьте свою трансляцию из любого места, где хотите Адаптеры, службы и т.д.

Intent sendBroadCastData = new Intent("your.filter");
sendBroadCastData.putExtra("fragment.data", myData);
LocalBroadcastManager.getInstance(context).sendBroadcast(sendBroadCastData);

Надеюсь, что это поможет другим.

Ответ 4

Я не знаю, что вы делаете, но похоже, что вам нужно использовать шаблон Observer, Callbacks или Listeners. Не может ли ваш фрагмент сделать что-то вроде:

myservice.addMyEventListener(myFragInstance);

а затем вы можете быть уведомлены о конкретном событии.

Ответ 5

Посмотрите на этот ответ fooobar.com/info/246342/...

Он использовал yourAdapter.notifyDataSetChanged(), который является предопределенным методом. Проверьте ссылку, чтобы увидеть, как ее сделать

Изменить: Когда ваша AsyncTask будет выполнена, вы должны сделать что-то вроде этого метода onPostExecute:

ResultFragment resultFrag = (ResultFragment) getSupportFragmentManager()
                                 .findFragmentByTag("FragToRefresh");
if (resultFrag != null) {
    resultFrag.refreshData(refreshedArray);
}

И в вашем ResultFragment вам нужно иметь метод refreshData, который выглядит примерно так:

public void refreshData(ArrayList<YourObject> data) {
   yourArray = new ArrayList<YourObject>(data);
   yourAdapter.notifyDataSetChanged();
}