从另一个片段中的目录更新片段中列表视图的元素
Updating Elements of Listview in a Fragment from a Catalog within another Fragment
标题可能有点乱,希望能正确表达我的问题。所以我正在开发一个简单的锻炼日志应用程序。我有图 1 中的片段 ActiveWorkout。当我按下粉红色的添加按钮时,我被定向到另一个片段,其中包含不同的练习作为列表,如图 2 所示。然后我要 select 一个练习(与 onItemClickListener) 并且该练习的标题应该发送回 ActiveWorkoutFragment 并添加到 Active Workout,所以它应该像图 3 一样。所以这里的问题是,我不知道如何保持我的 Active Workout 'alive',如果我想添加另一个练习并且当我再次按下粉红色的添加按钮时它不会是空白的,它应该被更新,所以最后它应该像图 4 中的那样。我正在考虑发送数据一个 Bundle,我也在代码中尝试过,但更困难的部分是在不删除之前添加的练习的情况下更新锻炼列表。顺便说一句,我尝试这样做的原因是因为数据实际上在 Firebase 数据库中,所以从某种意义上说,我正在尝试从 Workout 数据库中检索数据。
图片:
Image 1 Image 2 Image 3 Image 4
这是练习列表或目录:
public class ExercisesFragment extends Fragment {
private ListView lv;
private FirebaseListAdapter adapter;
private ArrayList<Exercise> exerciseList;
private ArrayList<String> nameList;
//private Adapter adapter;
public ExercisesFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_exercises, container, false);
lv = v.findViewById(R.id.lv);
Query query = FirebaseDatabase.getInstance().getReference().child("exerciseList");
FirebaseListOptions<ExerciseElement> options = new FirebaseListOptions.Builder<ExerciseElement>()
.setLayout(R.layout.exercise)
.setQuery(query, ExerciseElement.class)
.build();
adapter = new FirebaseListAdapter(options) {
@Override
protected void populateView(@NonNull View v, @NonNull Object model, int position) {
TextView bodypart = v.findViewById(R.id.bodypart);
TextView title = v.findViewById(R.id.title);
ExerciseElement el = (ExerciseElement) model;
bodypart.setText(el.getBodypart().toString());
title.setText(el.getTitle().toString());
}
};
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ExerciseElement el = (ExerciseElement) lv.getItemAtPosition(position);
String item = el.getTitle();
ActiveWorkoutFragment awf = new ActiveWorkoutFragment();
Bundle args = new Bundle();
args.putString("ExerciseTitle", item);
awf.setArguments(args);
getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, awf).commit();
//Navigation.findNavController(v).navigate(R.id.activeWorkoutFragment);
}
});
return v;
}
@Override
public void onStart() {
super.onStart();
adapter.startListening();
}
@Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
然后是ActiveWorkoutFragment,稍微长一点,不过上半部分不是重点。当我单击粉红色的添加按钮时,将调用 addNewExercise() 方法,因此我试图以某种方式在那里检索数据。
public class ActiveWorkoutFragment extends Fragment {
private Workout workout;
private TextView emptyRecyclerView;
private RecyclerView exerciseRecyclerView;
private ExerciseRecyclerViewAdapter adapter;
private WorkoutHistory workoutHistory;
private FloatingActionButton fab;
private FirebaseAuth mAuth;
private DatabaseReference databaseWorkouts;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_active_workout, container, false);
fab = v.findViewById(R.id.fab);
fab.setOnClickListener(this::addNewExercise);
setHasOptionsMenu(true);
workout = new Workout("WORKOUT");
if(savedInstanceState != null) {
workout = savedInstanceState.getParcelable("key");
}
emptyRecyclerView = v.findViewById(R.id.empty_recycler_view);
//buildRecyclerView(workout);
exerciseRecyclerView = v.findViewById(R.id.recycler_view_exercise);
// improves performance if size of RecyclerView content is fixed
// taken from developer.android.com
exerciseRecyclerView.setHasFixedSize(true);
// use a linear layout manager for RecyclerView
LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext());
exerciseRecyclerView.setLayoutManager(layoutManager);
// add divider
RecyclerView.ItemDecoration itemDecoration = new
DividerItemDecoration(this.getContext(), DividerItemDecoration.VERTICAL);
exerciseRecyclerView.addItemDecoration(itemDecoration);
// Create adapter and set its data set to workout
adapter = new ExerciseRecyclerViewAdapter(workout, this);
// Set up swipe to dismiss and ability to move RecyclerView items around
// Create callback object for ItemTouchHelper
ItemTouchHelper.Callback callback = new CustomItemTouchHelperCallback(adapter);
// Implement object created above
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(exerciseRecyclerView);
if (adapter.getItemCount() == 0)
{
showEmptyRecyclerViewText();
}
else
{
exerciseRecyclerView.setAdapter(adapter);
}
return v;
}
// Adds save button (check mark) to action bar
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.active_workout_action_bar, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save: {
List<Exercise> exercises = workout.getExercises();
mAuth = FirebaseAuth.getInstance();
String user_id = mAuth.getCurrentUser().getUid();
databaseWorkouts = FirebaseDatabase.getInstance().getReference("Workouts").child(user_id);
String id = databaseWorkouts.push().getKey();
workout = new Workout("abc", user_id, exercises);
databaseWorkouts.child(id).setValue(workout);
Toast.makeText(getContext(), "Workout saved", Toast.LENGTH_SHORT).show();
return true;
}
case R.id.action_delete: {
exerciseRecyclerView.requestFocus();
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Confirm deletion").setMessage("Are you sure you want to delete" +
" this workout?");
builder.setPositiveButton(android.R.string.yes, (dialog, which) -> {
try {
workoutHistory.removeWorkout(workout);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getContext(), "Workout deleted", Toast.LENGTH_SHORT).show();
});
builder.setNegativeButton(android.R.string.no, (dialog, which) -> {
dialog.dismiss();
});
builder.show();
return true;
}
default:
// unrecognized button pressed
return super.onOptionsItemSelected(item);
}
}
public void showEmptyRecyclerViewText()
{
emptyRecyclerView.setVisibility(View.VISIBLE);
}
public void addNewExercise(View view) {
Bundle bundle = getArguments();
String value = "";
if(bundle != null) {
value = bundle.getString("ExerciseTitle");
}
System.out.println("lala");
System.out.println(value);
Exercise newExercise = new Exercise(value, -1, -1);
if (exerciseRecyclerView.getAdapter() == null) {
exerciseRecyclerView.setAdapter(adapter);
}
emptyRecyclerView.setVisibility(View.INVISIBLE);
workout.addExercise(newExercise);
adapter.notifyItemInserted(workout.getExercises().size() - 1);
}
private void hideKeyboard(Context context, View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService
(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("key", workout);
}
}
尝试将其作为您项目的基础。向它添加视图和其他必要的方法,但是它将为您提供模块
的流程
//contract to update Framgents
public interface FragUpdater {
public void updateExerciseFrag(Exercise exercise);
}
public class ExerciseActiity extends AppCompatActivity implements FragUpdater {
FragmentManager fm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercise_actiity);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
gotoActiveWorkoutFragment();
}
});
fm = getSupportFragmentManager();
gotoExercisesFragment();
}
private void gotoActiveWorkoutFragment() {
ActiveWorkoutFragment activeWorkoutFragment = new ActiveWorkoutFragment();
Bundle bundle = new Bundle();
activeWorkoutFragment.setArguments(bundle);
fm.beginTransaction().add(R.id.content_frame, activeWorkoutFragment, "ExerciseSelectionFrag").addToBackStack(null).commit();
}
private void gotoExercisesFragment() {
ExercisesFragment exercisesFragment = new ExercisesFragment();
Bundle bundle = new Bundle();
exercisesFragment.setArguments(bundle);
fm.beginTransaction().replace(R.id.content_frame, exercisesFragment, "ExerciseDisplayFrag").commit();
}
@Override
public void updateExerciseFrag(Exercise exercise) {
// Get Fragment ExercisesFragment
ExercisesFragment frag = (ExercisesFragment)
fm.findFragmentByTag("ExerciseDisplayFrag");
if (frag == null) {
return;
}
frag.updateList(exercise);
}
}
public class ExercisesFragment extends Fragment {
//here update your list in ExerciseFragment
public void updateList(Exercise exercise) {}
}
public class ActiveWorkoutFragment extends Fragment {
FragUpdater fragUpdater;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragUpdater = (ExerciseActiity) getActivity();
}
private void selectListItem(Exercise exercise) {
fragUpdater.updateExerciseFrag(exercise);
getActivity().getSupportFragmentManager().popBackStack();
}
}
标题可能有点乱,希望能正确表达我的问题。所以我正在开发一个简单的锻炼日志应用程序。我有图 1 中的片段 ActiveWorkout。当我按下粉红色的添加按钮时,我被定向到另一个片段,其中包含不同的练习作为列表,如图 2 所示。然后我要 select 一个练习(与 onItemClickListener) 并且该练习的标题应该发送回 ActiveWorkoutFragment 并添加到 Active Workout,所以它应该像图 3 一样。所以这里的问题是,我不知道如何保持我的 Active Workout 'alive',如果我想添加另一个练习并且当我再次按下粉红色的添加按钮时它不会是空白的,它应该被更新,所以最后它应该像图 4 中的那样。我正在考虑发送数据一个 Bundle,我也在代码中尝试过,但更困难的部分是在不删除之前添加的练习的情况下更新锻炼列表。顺便说一句,我尝试这样做的原因是因为数据实际上在 Firebase 数据库中,所以从某种意义上说,我正在尝试从 Workout 数据库中检索数据。
图片:
Image 1 Image 2 Image 3 Image 4
这是练习列表或目录:
public class ExercisesFragment extends Fragment {
private ListView lv;
private FirebaseListAdapter adapter;
private ArrayList<Exercise> exerciseList;
private ArrayList<String> nameList;
//private Adapter adapter;
public ExercisesFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_exercises, container, false);
lv = v.findViewById(R.id.lv);
Query query = FirebaseDatabase.getInstance().getReference().child("exerciseList");
FirebaseListOptions<ExerciseElement> options = new FirebaseListOptions.Builder<ExerciseElement>()
.setLayout(R.layout.exercise)
.setQuery(query, ExerciseElement.class)
.build();
adapter = new FirebaseListAdapter(options) {
@Override
protected void populateView(@NonNull View v, @NonNull Object model, int position) {
TextView bodypart = v.findViewById(R.id.bodypart);
TextView title = v.findViewById(R.id.title);
ExerciseElement el = (ExerciseElement) model;
bodypart.setText(el.getBodypart().toString());
title.setText(el.getTitle().toString());
}
};
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ExerciseElement el = (ExerciseElement) lv.getItemAtPosition(position);
String item = el.getTitle();
ActiveWorkoutFragment awf = new ActiveWorkoutFragment();
Bundle args = new Bundle();
args.putString("ExerciseTitle", item);
awf.setArguments(args);
getFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, awf).commit();
//Navigation.findNavController(v).navigate(R.id.activeWorkoutFragment);
}
});
return v;
}
@Override
public void onStart() {
super.onStart();
adapter.startListening();
}
@Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
然后是ActiveWorkoutFragment,稍微长一点,不过上半部分不是重点。当我单击粉红色的添加按钮时,将调用 addNewExercise() 方法,因此我试图以某种方式在那里检索数据。
public class ActiveWorkoutFragment extends Fragment {
private Workout workout;
private TextView emptyRecyclerView;
private RecyclerView exerciseRecyclerView;
private ExerciseRecyclerViewAdapter adapter;
private WorkoutHistory workoutHistory;
private FloatingActionButton fab;
private FirebaseAuth mAuth;
private DatabaseReference databaseWorkouts;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_active_workout, container, false);
fab = v.findViewById(R.id.fab);
fab.setOnClickListener(this::addNewExercise);
setHasOptionsMenu(true);
workout = new Workout("WORKOUT");
if(savedInstanceState != null) {
workout = savedInstanceState.getParcelable("key");
}
emptyRecyclerView = v.findViewById(R.id.empty_recycler_view);
//buildRecyclerView(workout);
exerciseRecyclerView = v.findViewById(R.id.recycler_view_exercise);
// improves performance if size of RecyclerView content is fixed
// taken from developer.android.com
exerciseRecyclerView.setHasFixedSize(true);
// use a linear layout manager for RecyclerView
LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext());
exerciseRecyclerView.setLayoutManager(layoutManager);
// add divider
RecyclerView.ItemDecoration itemDecoration = new
DividerItemDecoration(this.getContext(), DividerItemDecoration.VERTICAL);
exerciseRecyclerView.addItemDecoration(itemDecoration);
// Create adapter and set its data set to workout
adapter = new ExerciseRecyclerViewAdapter(workout, this);
// Set up swipe to dismiss and ability to move RecyclerView items around
// Create callback object for ItemTouchHelper
ItemTouchHelper.Callback callback = new CustomItemTouchHelperCallback(adapter);
// Implement object created above
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(exerciseRecyclerView);
if (adapter.getItemCount() == 0)
{
showEmptyRecyclerViewText();
}
else
{
exerciseRecyclerView.setAdapter(adapter);
}
return v;
}
// Adds save button (check mark) to action bar
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.active_workout_action_bar, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save: {
List<Exercise> exercises = workout.getExercises();
mAuth = FirebaseAuth.getInstance();
String user_id = mAuth.getCurrentUser().getUid();
databaseWorkouts = FirebaseDatabase.getInstance().getReference("Workouts").child(user_id);
String id = databaseWorkouts.push().getKey();
workout = new Workout("abc", user_id, exercises);
databaseWorkouts.child(id).setValue(workout);
Toast.makeText(getContext(), "Workout saved", Toast.LENGTH_SHORT).show();
return true;
}
case R.id.action_delete: {
exerciseRecyclerView.requestFocus();
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Confirm deletion").setMessage("Are you sure you want to delete" +
" this workout?");
builder.setPositiveButton(android.R.string.yes, (dialog, which) -> {
try {
workoutHistory.removeWorkout(workout);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getContext(), "Workout deleted", Toast.LENGTH_SHORT).show();
});
builder.setNegativeButton(android.R.string.no, (dialog, which) -> {
dialog.dismiss();
});
builder.show();
return true;
}
default:
// unrecognized button pressed
return super.onOptionsItemSelected(item);
}
}
public void showEmptyRecyclerViewText()
{
emptyRecyclerView.setVisibility(View.VISIBLE);
}
public void addNewExercise(View view) {
Bundle bundle = getArguments();
String value = "";
if(bundle != null) {
value = bundle.getString("ExerciseTitle");
}
System.out.println("lala");
System.out.println(value);
Exercise newExercise = new Exercise(value, -1, -1);
if (exerciseRecyclerView.getAdapter() == null) {
exerciseRecyclerView.setAdapter(adapter);
}
emptyRecyclerView.setVisibility(View.INVISIBLE);
workout.addExercise(newExercise);
adapter.notifyItemInserted(workout.getExercises().size() - 1);
}
private void hideKeyboard(Context context, View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService
(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("key", workout);
}
}
尝试将其作为您项目的基础。向它添加视图和其他必要的方法,但是它将为您提供模块
的流程//contract to update Framgents
public interface FragUpdater {
public void updateExerciseFrag(Exercise exercise);
}
public class ExerciseActiity extends AppCompatActivity implements FragUpdater {
FragmentManager fm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercise_actiity);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
gotoActiveWorkoutFragment();
}
});
fm = getSupportFragmentManager();
gotoExercisesFragment();
}
private void gotoActiveWorkoutFragment() {
ActiveWorkoutFragment activeWorkoutFragment = new ActiveWorkoutFragment();
Bundle bundle = new Bundle();
activeWorkoutFragment.setArguments(bundle);
fm.beginTransaction().add(R.id.content_frame, activeWorkoutFragment, "ExerciseSelectionFrag").addToBackStack(null).commit();
}
private void gotoExercisesFragment() {
ExercisesFragment exercisesFragment = new ExercisesFragment();
Bundle bundle = new Bundle();
exercisesFragment.setArguments(bundle);
fm.beginTransaction().replace(R.id.content_frame, exercisesFragment, "ExerciseDisplayFrag").commit();
}
@Override
public void updateExerciseFrag(Exercise exercise) {
// Get Fragment ExercisesFragment
ExercisesFragment frag = (ExercisesFragment)
fm.findFragmentByTag("ExerciseDisplayFrag");
if (frag == null) {
return;
}
frag.updateList(exercise);
}
}
public class ExercisesFragment extends Fragment {
//here update your list in ExerciseFragment
public void updateList(Exercise exercise) {}
}
public class ActiveWorkoutFragment extends Fragment {
FragUpdater fragUpdater;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragUpdater = (ExerciseActiity) getActivity();
}
private void selectListItem(Exercise exercise) {
fragUpdater.updateExerciseFrag(exercise);
getActivity().getSupportFragmentManager().popBackStack();
}
}