私はViewPager
を持っていて、同じ種類のいくつかのフラグメントを表示するためにFragmentAdapter
を使用しています。これらのフラグメントは基本的に同じクラスからインスタンス化されますが、ListView
を使用して異なる情報を表示しています。 (明らかに、ListView
はArrayAdapter
によって作成されています。)
バックグラウンドサービスも実行されており、インターネットから常にデータを受信しています。バックグラウンドサービスから特定のイベントが通知されたときに、ViewPager
の特定のフラグメントを更新できるようにしたい。
どうやってやるの?コードスニペットをいただければ幸いです。
(ちなみに、私は この同様の質問 を見ましたが、彼らの提案をどのように使用するかわかりません!)
それをすべてもっと簡単にするために:ViewPagerでの私の活動:
[フラグメント0] [フラグメント1] [フラグメント2]
バックグラウンドサービスは、(ブロードキャストを介して)フラグメント1のListView
を更新するように指示します。
編集:サンプルコードは次のとおりです。
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:私がしていることが、私がやりたいことを処理する正しい方法であるかどうかを知りたい...他の解決策大歓迎です!
これを試して、
すべてのフラグメントにブロードキャストレシーバーを登録します...このように
たとえば、次のように、すべてのクラスでブロードキャストレシーバーを拡張するクラスを作成します。
_public class FragmentReceiver1 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
_
このレシーバーをフラグメントのonCreateに登録します...
例えば。 getActivity().registerReceiver(new FragmentReceiver1(), new IntentFilter("fragmentupdater"));
次に、フラグメント1に1、フラグメント2に2など、各フラグメントに一意のIDを割り当てます。
これで、データを渡し、フラグメントを更新するときはいつでも、インテント内のデータとインテントフィルターとしての「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
関数で渡された一意のIDであるかどうかを確認できます...取得するインテントは上で渡した意図
試しましたか 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
}
編集:私は注意深く読んだ! instanceOf
は、Fragment
を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 について)、ソースコードを投稿することを検討してください。そうすれば、必要なものを推測する必要がなくなります。
私は同じ問題を抱えていましたが、次のように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);
それが他の人に役立つことを願っています。
あなたが何をしているのかよくわかりませんが、オブザーバーパターン、コールバック、またはリスナーを使用する必要があるようです。あなたのフラグメントはただ次のようなことをすることはできません:
myservice.addMyEventListener(myFragInstance);
そうすれば、「特定のイベントを通知」することができます。
この答えを見てください https://stackoverflow.com/a/1638865
彼は、事前定義されたメソッドである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();
}
すべてをシンプルにするためにイベントバスを使用する必要がありました https://github.com/greenrobot/EventBus