通过 FragmentStateAdapter 将数据从 Activity 传递到 Fragment
Pass data from Activity to Fragment via FragmentStateAdapter
我目前正在为评分助手应用程序开发个人项目应用程序。目的是使用该应用程序跟踪每个玩家的分数,并获得高分和其他花哨的功能。
现在,我有一个使用 ViewPager2
的选项卡 Activity。对于那些熟悉它的人来说,你会比我知道的更多,但我注意到我从来没有在 activity 中实例化我的 Fragment
classes,只在FragmentStateAdapter
。在我的 activity 中,我只使用了两个选项卡,一个用于游戏方面,一个用于点数显示。考虑到这一点,我的 activity class 看起来像这样:
EightHoleActivity.java
package com.example.game;
import android.content.Intent;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
public class EightHoleActivity extends AppCompatActivity {
private long gameID;
private RoomDB database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eight_hole);
Intent intent = getIntent();
gameID = intent.getLongExtra("GameID", 0);
database = RoomDB.getInstance(EightHoleActivity.this);
ViewPager2 viewPager2 = findViewById(R.id.eight_hole_view_pager);
viewPager2.setAdapter(new EightHolePagerAdapter(this));
TabLayout tabLayout = findViewById(R.id.eight_hole_tabs);
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
tabLayout, viewPager2, (tab, position) -> {
switch (position){
case 0: {
tab.setText("Current game");
tab.setIcon(R.drawable.ic_twotone_games_24);
break;
}
default: {
tab.setText("Scores");
tab.setIcon(R.drawable.ic_baseline_list_24);
break;
}
}
}
);
tabLayoutMediator.attach();
}
}
如您所见,我有一个 RoomDatabase
用于在应用程序中存储数据。当我有意开始这个 activity 时,我传递了正在玩的游戏的 ID
。这是我遇到问题的地方。
我想做的事情:
我想将从 intent.getLongExtra("GameID", 0)
获得的变量 gameID
一直传递到 EightHoleScoresFragment
class.
我没有使用 Bundle
和 putParcelableArrayList()
这是我使用的其他 classes。
请注意,class Participants.java 是我要使用 gameID
变量提取的内容。
Participants.java
package com.example.game;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.PrimaryKey;
import java.util.Objects;
@Entity(tableName = "participants", foreignKeys = {
@ForeignKey(entity = Player.class, parentColumns = "id", childColumns = "player_id", onDelete = ForeignKey.CASCADE),
@ForeignKey(entity = Game.class, parentColumns = "id", childColumns = "game_id", onDelete = ForeignKey.CASCADE)})
public class Participant implements Parcelable {
@PrimaryKey(autoGenerate = true)
private long id;
@ColumnInfo(name = "player_id", index = true)
private long playerID;
@ColumnInfo(name = "game_id", index = true)
private long gameID;
@ColumnInfo(name = "score")
private int score;
protected Participant(Parcel in) {
id = in.readLong();
playerID = in.readLong();
gameID = in.readLong();
score = in.readInt();
}
public static final Creator<Participant> CREATOR = new Creator<Participant>() {
@Override
public Participant createFromParcel(Parcel in) {
return new Participant(in);
}
@Override
public Participant[] newArray(int size) {
return new Participant[size];
}
};
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getPlayerID() {
return playerID;
}
public void setPlayerID(long playerID) {
this.playerID = playerID;
}
public long getGameID() {
return gameID;
}
public void setGameID(long gameID) {
this.gameID = gameID;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Participant(long playerID, long gameID){
this.playerID = playerID;
this.gameID = gameID;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof Participant)) return false;
Participant participant = (Participant) obj;
if (id != participant.id) return false;
return Objects.equals(score, participant.score) || Objects.equals(playerID, participant.playerID) || Objects.equals(gameID, participant.gameID);
}
@Override
public int hashCode() {
int result = (int) id;
result = (int) (31 * result + playerID + gameID + score);
return result;
}
@Override
public String toString() {
return "Participant{" +
"ID=" + id +
", PlayerID='" + playerID + '\'' +
", GameID='" + gameID + '\'' +
", Score='" + score + '\'' +
'}';
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(id);
dest.writeLong(playerID);
dest.writeLong(gameID);
dest.writeInt(score);
}
}
EightHolePagerAdapter.java
package com.example.game;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
public class EightHolePagerAdapter extends FragmentStateAdapter {
public EightHolePagerAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position){
case 0:
return new EightHoleGameFragment();
default:
return new EightHoleScoresFragment();
}
}
@Override
public int getItemCount() {
return 2;
}
}
EightHoleScoresFragment.java
package com.example.game;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;
public class EightHoleScoresFragment extends Fragment {
private ArrayList<Participant> participants = new ArrayList<Participant>();
public EightHoleScoresFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_eight_hole_scores, container, false);
ListView listView = (ListView) view.findViewById(R.id.eight_hole_current_scores_list);
ScoresAdapter adapter = new ScoresAdapter(getActivity(), R.layout.scores_adapter_layout, participants);
listView.setAdapter(adapter);
return view;
}
}
对于摘要代码量,我深表歉意。我觉得有必要了解正在发生的事情。我已经按照我所说的那样尝试使用 Bundle
,遵循网站上的各种答案,但 none 已经奏效。我想知道是否可以使用一种链接回父 EightHoleActivity
的方法将意图的内容直接传递给 EightHoleScoresFragment
但我不确定...
提前致谢!
请试试这个方法
在Activity中:
将 gameId 作为额外参数传递并在 Adapter 中接收
viewPager2.setAdapter(new EightHolePagerAdapter(this, gameID));
在 ViewPagerAdapter 中:
EightHoleScoresFragment
获取 gameId 并调用片段 newInstance
public class EightHolePagerAdapter extends FragmentStateAdapter {
private long gameId;
public EightHolePagerAdapter(@NonNull FragmentActivity fragmentActivity, long gameId) {
super(fragmentActivity);
this.gameId = gameId;
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position){
case 0:
return new EightHoleGameFragment();
default:
return EightHoleScoresFragment.newInstance(gameId);
}
}
@Override
public int getItemCount() {
return 2;
}
}
在你的片段中:
以这种方式在片段中接收 gameId 参数。
public class EightHoleScoresFragment extends Fragment {
private static final String ARG_GAME_ID = "game_id";
private long mGameId;
public static EightHoleScoresFragment newInstance(long gameId) {
EightHoleScoresFragment fragment = new EightHoleScoresFragment();
Bundle args = new Bundle();
args.putLong(ARG_GAME_ID, gameId);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mGameId = getArguments().getLong(ARG_GAME_ID);
}
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d("EightHoleScoresFragment", "Game Id = " + mGameId);
}
}
我目前正在为评分助手应用程序开发个人项目应用程序。目的是使用该应用程序跟踪每个玩家的分数,并获得高分和其他花哨的功能。
现在,我有一个使用 ViewPager2
的选项卡 Activity。对于那些熟悉它的人来说,你会比我知道的更多,但我注意到我从来没有在 activity 中实例化我的 Fragment
classes,只在FragmentStateAdapter
。在我的 activity 中,我只使用了两个选项卡,一个用于游戏方面,一个用于点数显示。考虑到这一点,我的 activity class 看起来像这样:
EightHoleActivity.java
package com.example.game;
import android.content.Intent;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
public class EightHoleActivity extends AppCompatActivity {
private long gameID;
private RoomDB database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_eight_hole);
Intent intent = getIntent();
gameID = intent.getLongExtra("GameID", 0);
database = RoomDB.getInstance(EightHoleActivity.this);
ViewPager2 viewPager2 = findViewById(R.id.eight_hole_view_pager);
viewPager2.setAdapter(new EightHolePagerAdapter(this));
TabLayout tabLayout = findViewById(R.id.eight_hole_tabs);
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
tabLayout, viewPager2, (tab, position) -> {
switch (position){
case 0: {
tab.setText("Current game");
tab.setIcon(R.drawable.ic_twotone_games_24);
break;
}
default: {
tab.setText("Scores");
tab.setIcon(R.drawable.ic_baseline_list_24);
break;
}
}
}
);
tabLayoutMediator.attach();
}
}
如您所见,我有一个 RoomDatabase
用于在应用程序中存储数据。当我有意开始这个 activity 时,我传递了正在玩的游戏的 ID
。这是我遇到问题的地方。
我想做的事情:
我想将从 intent.getLongExtra("GameID", 0)
获得的变量 gameID
一直传递到 EightHoleScoresFragment
class.
我没有使用 Bundle
和 putParcelableArrayList()
这是我使用的其他 classes。
请注意,class Participants.java 是我要使用 gameID
变量提取的内容。
Participants.java
package com.example.game;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.PrimaryKey;
import java.util.Objects;
@Entity(tableName = "participants", foreignKeys = {
@ForeignKey(entity = Player.class, parentColumns = "id", childColumns = "player_id", onDelete = ForeignKey.CASCADE),
@ForeignKey(entity = Game.class, parentColumns = "id", childColumns = "game_id", onDelete = ForeignKey.CASCADE)})
public class Participant implements Parcelable {
@PrimaryKey(autoGenerate = true)
private long id;
@ColumnInfo(name = "player_id", index = true)
private long playerID;
@ColumnInfo(name = "game_id", index = true)
private long gameID;
@ColumnInfo(name = "score")
private int score;
protected Participant(Parcel in) {
id = in.readLong();
playerID = in.readLong();
gameID = in.readLong();
score = in.readInt();
}
public static final Creator<Participant> CREATOR = new Creator<Participant>() {
@Override
public Participant createFromParcel(Parcel in) {
return new Participant(in);
}
@Override
public Participant[] newArray(int size) {
return new Participant[size];
}
};
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getPlayerID() {
return playerID;
}
public void setPlayerID(long playerID) {
this.playerID = playerID;
}
public long getGameID() {
return gameID;
}
public void setGameID(long gameID) {
this.gameID = gameID;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Participant(long playerID, long gameID){
this.playerID = playerID;
this.gameID = gameID;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof Participant)) return false;
Participant participant = (Participant) obj;
if (id != participant.id) return false;
return Objects.equals(score, participant.score) || Objects.equals(playerID, participant.playerID) || Objects.equals(gameID, participant.gameID);
}
@Override
public int hashCode() {
int result = (int) id;
result = (int) (31 * result + playerID + gameID + score);
return result;
}
@Override
public String toString() {
return "Participant{" +
"ID=" + id +
", PlayerID='" + playerID + '\'' +
", GameID='" + gameID + '\'' +
", Score='" + score + '\'' +
'}';
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(id);
dest.writeLong(playerID);
dest.writeLong(gameID);
dest.writeInt(score);
}
}
EightHolePagerAdapter.java
package com.example.game;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
public class EightHolePagerAdapter extends FragmentStateAdapter {
public EightHolePagerAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position){
case 0:
return new EightHoleGameFragment();
default:
return new EightHoleScoresFragment();
}
}
@Override
public int getItemCount() {
return 2;
}
}
EightHoleScoresFragment.java
package com.example.game;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;
public class EightHoleScoresFragment extends Fragment {
private ArrayList<Participant> participants = new ArrayList<Participant>();
public EightHoleScoresFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_eight_hole_scores, container, false);
ListView listView = (ListView) view.findViewById(R.id.eight_hole_current_scores_list);
ScoresAdapter adapter = new ScoresAdapter(getActivity(), R.layout.scores_adapter_layout, participants);
listView.setAdapter(adapter);
return view;
}
}
对于摘要代码量,我深表歉意。我觉得有必要了解正在发生的事情。我已经按照我所说的那样尝试使用 Bundle
,遵循网站上的各种答案,但 none 已经奏效。我想知道是否可以使用一种链接回父 EightHoleActivity
的方法将意图的内容直接传递给 EightHoleScoresFragment
但我不确定...
提前致谢!
请试试这个方法
在Activity中:
将 gameId 作为额外参数传递并在 Adapter 中接收
viewPager2.setAdapter(new EightHolePagerAdapter(this, gameID));
在 ViewPagerAdapter 中:
EightHoleScoresFragment
获取 gameId 并调用片段 newInstance
public class EightHolePagerAdapter extends FragmentStateAdapter {
private long gameId;
public EightHolePagerAdapter(@NonNull FragmentActivity fragmentActivity, long gameId) {
super(fragmentActivity);
this.gameId = gameId;
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position){
case 0:
return new EightHoleGameFragment();
default:
return EightHoleScoresFragment.newInstance(gameId);
}
}
@Override
public int getItemCount() {
return 2;
}
}
在你的片段中:
以这种方式在片段中接收 gameId 参数。
public class EightHoleScoresFragment extends Fragment {
private static final String ARG_GAME_ID = "game_id";
private long mGameId;
public static EightHoleScoresFragment newInstance(long gameId) {
EightHoleScoresFragment fragment = new EightHoleScoresFragment();
Bundle args = new Bundle();
args.putLong(ARG_GAME_ID, gameId);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mGameId = getArguments().getLong(ARG_GAME_ID);
}
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d("EightHoleScoresFragment", "Game Id = " + mGameId);
}
}