我无法通过广播将数据发送到活动中的片段
Posted
技术标签:
【中文标题】我无法通过广播将数据发送到活动中的片段【英文标题】:I can't send data to a fragment from an activity with broadcast 【发布时间】:2020-06-22 17:48:59 【问题描述】:我正在尝试将数据从活动发送到片段。数据是当前单击的项目的名称,我需要,因为我想进行查询。但数据永远不会发送。我也尝试在调用fragment.begingTrascation之前发送广播,但仍然不起作用, 我还更改了常量的名称,但仍然不会触发来自 Fragment 的广播。 我不知道为什么不起作用,我该怎么做才能解决这个问题?
private NavigationView.OnNavigationItemSelectedListener navigationListener = new NavigationView.OnNavigationItemSelectedListener()
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item)
if (item.getItemId() == R.id.nav_today)
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, new TodayFragment())
.commit();
else if (item.getItemId() == R.id.nav_inbox)
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, new InboxFragment())
.commit();
else if (item.getItemId() == R.id.nav_add_list)
ListBottomSheet bottomSheet = new ListBottomSheet();
bottomSheet.showNow(getSupportFragmentManager(), "bottomSheetList");
else if (item.getItemId() == R.id.nav_account)
startActivity(new Intent(HomeDrawerActivity.this, AccountActivity.class));
else if (item.getItemId() == R.id.nav_random_task)
startActivity(new Intent(HomeDrawerActivity.this, RandomTaskActivity.class));
else
/* one of the list items
was clicked therefore
get the data form db
*/
item.setCheckable(true);
item.setChecked(true);
String listName = item.getTitle().toString();
Toast.makeText(HomeDrawerActivity.this, listName, Toast.LENGTH_LONG).show();
/* create the fragment */
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, new ListFragment())
.commit();
/* send data to the fragment */
Intent intent = new Intent(LIST_ACTION);
intent.putExtra(KEY_LIST_NAME, listName);
LocalBroadcastManager.getInstance(HomeDrawerActivity.this).sendBroadcast(intent);
drawer.closeDrawer(GravityCompat.START);
return true;
;
public class ListFragment extends Fragment
private Context context;
private String documentName;
private ListAdaptor listAdaptor;
private RecyclerView recyclerViewList;
private ColorDrawable swipeBackgroundRight = new ColorDrawable(Color.parseColor("#FF0000"));
private ColorDrawable swipeBackgroundLeft = new ColorDrawable(Color.parseColor("#1E88E5"));
private Drawable iconDelete;
private Drawable iconComplete;
private SoundPool soundPool;
private int soundId;
private FirebaseFirestore firestore = FirebaseFirestore.getInstance();
private CollectionReference collectionReference = firestore.collection("Users")
.document(FirebaseAuth.getInstance().getCurrentUser().getUid())
.collection("Lists");
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.list_fragment, container, false);
LocalBroadcastManager.getInstance(context)
.registerReceiver(broadcastReceiver, new IntentFilter(HomeDrawerActivity.LIST_ACTION));
iconDelete = ContextCompat.getDrawable(getActivity(), R.drawable.ic_delete);
iconComplete = ContextCompat.getDrawable(getActivity(), R.drawable.ic_completed);
if (!TextUtils.isEmpty(documentName))
collectionReference.document(documentName);
else
Toast.makeText(getActivity(), "Error", Toast.LENGTH_SHORT).show();
/* create the option query
for the recycler
*/
Query query = collectionReference;
FirestoreRecyclerOptions<Task> options =
new FirestoreRecyclerOptions.Builder<Task>()
.setQuery(query, Task.class)
.build();
listAdaptor = new ListAdaptor(options);
recyclerViewList = rootView.findViewById(R.id.recycler_view_list);
recyclerViewList.setHasFixedSize(true);
recyclerViewList.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerViewList.setAdapter(listAdaptor);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
AudioAttributes audioAttributes =
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
soundPool = new SoundPool.Builder()
.setMaxStreams(1)
.setAudioAttributes(audioAttributes)
.build();
else
soundPool = new SoundPool(1, AudioManager.STREAM_RING, 0);
soundId = soundPool.load(getActivity(), R.raw.completed, 1);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT)
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target)
return true;
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction)
if (direction == ItemTouchHelper.RIGHT)
listAdaptor.delete(viewHolder.getAdapterPosition());
Toast.makeText(context, "Task deleted", Toast.LENGTH_SHORT).show();
else if (direction == ItemTouchHelper.LEFT)
listAdaptor.update(viewHolder.getAdapterPosition());
soundPool.play(soundId, 1, 1, 1, 0, 1);
Toast.makeText(context, "Task completed", Toast.LENGTH_SHORT).show();
swipeBackgroundRight.setBounds(0, 0, 0, 0);
iconDelete.setBounds(0, 0, 0, 0);
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive)
View itemView = viewHolder.itemView;
int iconMargin = (itemView.getHeight() - iconDelete.getIntrinsicHeight()) / 2;
if (dX > 0)
swipeBackgroundRight.setBounds(itemView.getLeft(), itemView.getTop(), (int) dX, itemView.getBottom());
iconDelete.setBounds(itemView.getLeft() + iconMargin, itemView.getTop() + iconMargin, itemView.getLeft() + iconMargin + iconDelete.getIntrinsicWidth(), itemView.getBottom() - iconMargin);
else if (dX < 0)
swipeBackgroundLeft.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
iconComplete.setBounds(itemView.getRight() - iconMargin - iconComplete.getIntrinsicWidth(), itemView.getTop() + iconMargin, itemView.getRight() - iconMargin,
itemView.getBottom() - iconMargin);
else
swipeBackgroundLeft.setBounds(0, 0, 0, 0);
swipeBackgroundRight.setBounds(0, 0, 0, 0);
c.save();
swipeBackgroundRight.draw(c);
swipeBackgroundLeft.draw(c);
if (dX > 0)
c.clipRect(itemView.getLeft(), itemView.getTop(), (int) dX, itemView.getBottom());
else
c.clipRect(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
iconDelete.draw(c);
iconComplete.draw(c);
c.restore();
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
).attachToRecyclerView(recyclerViewList);
return rootView;
@Override
public void onAttach(@NonNull Context context)
super.onAttach(context);
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
if (HomeDrawerActivity.LIST_ACTION.equals(intent.getAction()))
/* get the data from db */
documentName = intent.getStringExtra(HomeDrawerActivity.KEY_LIST_NAME);
Toast.makeText(getActivity(), "List fragment" + documentName, Toast.LENGTH_LONG).show();
;
@Override
public void onStart()
super.onStart();
listAdaptor.startListening();
@Override
public void onDestroyView()
super.onDestroyView();
LocalBroadcastManager.getInstance(context).unregisterReceiver(broadcastReceiver);
【问题讨论】:
【参考方案1】:如果您在Fragment
事务开始之前发送广播,Fragment
很可能无法及时设置其BroadcastReceiver
来捕捉传输。
但在您的情况下,您可以在开始事务之前将要传递给Fragment
的数据添加到ListFragment
实例的参数Bundle
:
String listName = item.getTitle().toString();
/* create the fragment */
ListFragment listFragment = new ListFragment();
/* store data in arguments Bundle */
Bundle args = new Bundle();
args.putString(KEY_LIST_NAME, listName);
listFragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, listFragment )
.commit();
在ListFragment
,您可以通过如下方式访问数据:
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.list_fragment, container, false);
Bundle args = getArguments();
String listName = args.getString(KEY_LIST_NAME);
// ....
【讨论】:
尝试在空对象引用上调用虚拟方法'java.lang.String android.os.Bundle.getString(java.lang.String)' @Scepticul - 你使用 listFragment.setArguments(args);在开始交易之前? 是的,和你的例子一模一样。 @Scepticul - 感谢您告诉我,祝您项目顺利! 再次感谢您!以上是关于我无法通过广播将数据发送到活动中的片段的主要内容,如果未能解决你的问题,请参考以下文章