我有一个ViewPager
,它正在使用FragmentAdapter
来显示相同类型的多个片段。虽然这些片段基本上是从同一个类实例化的,但它们使用ListView
来显示不同的信息。 (显然ListView
被ArrayAdapter
所包围。)
后台服务也在运行,并且不断从Internet接收数据。我希望能够在我的后台服务通知我特定事件时更新ViewPager
中的特定片段。
我怎样才能做到这一点?
我们非常感谢您的代码片段!
(顺便说一下,我看到this similar question,但我不知道如何使用他们的建议!)
更简单:
我使用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: 我想知道我在做什么,是处理我想要做的正确方法......也欢迎任何其他解决方案!
答案 0 :(得分:40)
试试这个,
在所有片段中注册广播接收器......就像这样
创建一个扩展所有类中广播接收器的类,例如:
public class FragmentReceiver1 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
并将此接收器注册到片段的onCreate ...
例如。 getActivity().registerReceiver(new FragmentReceiver1(), new IntentFilter("fragmentupdater"));
现在为每个片段分配一个唯一的ID,如Fragment1为1,Fragment2为2,同样
现在每当你想传递任何数据并更新任何片段时,只需发送一个包含intent in data和“fragmentupdater”作为intent-filter的广播...
例如:
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来验证数据是否是同一个片段...,你得到的意图,是我们上面传递的意图
答案 1 :(得分:5)
您是否尝试过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)并发布您的源代码,这样我们就不必猜测您需要什么。
答案 2 :(得分:0)
我不知道你在做什么,但听起来你需要使用Observer模式,Callbacks或Listeners。你的片段不能像以下那样:
myservice.addMyEventListener(myFragInstance);
然后您可以“收到特定事件的通知。”
答案 3 :(得分:0)
看看这个答案https://stackoverflow.com/a/16388650
他使用了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();
}
答案 4 :(得分:0)
不得不使用事件总线来简化一切https://github.com/greenrobot/EventBus
答案 5 :(得分:0)
我不确定这是正确的做法
1. 在片段中创建一个公共函数,您将调用它来接收数据。
public void refreshList(List<String> yourData) {
//referesh your fragment views here
}
2.创建全局片段对象
YourFragment frag = new YourFragment();
3. 将其传递给包含活动中的视图分页器
4.向视图寻呼机添加页面更改侦听器
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position) {
case 0:
break;
case 1:
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
此处case 0:在选择第一个片段时调用,case 1:在第二个片段被选中时调用..
5.根据其在视图分页器中的位置调用您的函数
case 0: frag.refreshList(yourList);