#java #android #android-studio
#java #Android #android-studio
Вопрос:
Проблема:
Я пытаюсь открыть пользовательский диалог после нажатия кнопки в моем фрагменте с вкладками. Похоже, что мое действие MainActivity отправляется в диалоговое окно, в то время как я хочу, чтобы был отправлен мой фрагмент с вкладками (GroupFragment), чтобы я мог изменить EditText (на данный момент) в этом фрагменте.
Код:
public class GroupFragment extends Fragment implements AddGroupDialog.AddGroupDialogListener {
private Button addGroupButton;
private TextView textViewNoGroups;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_group, container, false);
addGroupButton = view.findViewById(R.id.addGroupButton);
textViewNoGroups = view.findViewById(R.id.textViewNoGroups);
addGroupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addNewGroupDialog();
}
});
scaleAnimation(addGroupButton);
return view;
}
private void scaleAnimation(View v){
Animator scale = ObjectAnimator.ofPropertyValuesHolder(v,
PropertyValuesHolder.ofFloat(View.SCALE_X, 0, 1.2f, 1),
PropertyValuesHolder.ofFloat(View.SCALE_Y, 0, 1.2f, 1)
);
scale.setDuration(600);
scale.start();
}
private void addNewGroupDialog(){
AddGroupDialog dialog = new AddGroupDialog();
assert getFragmentManager() != null;
dialog.show(getFragmentManager(), "add new group dialog");
}
@Override
public void applyString(String groupName) {
textViewNoGroups.setText(groupName);
}
}
public class AddGroupDialog extends AppCompatDialogFragment {
private EditText editTextGroupName;
private AddGroupDialogListener listener;
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.layout_add_new_group_dialog, null);
builder.setView(view)
.setTitle("")
.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String groupName = editTextGroupName.getText().toString();
listener.applyString(groupName);
}
});
editTextGroupName = view.findViewById(R.id.editTextGroupName);
return builder.create();
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
listener = (AddGroupDialogListener) context;
} catch (ClassCastException e){
throw new ClassCastException(context.toString()
"Must implement AddGroupDialogListener");
}
}
public interface AddGroupDialogListener{
void applyString(String groupName);
}
}
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
@StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position){
case 0:
fragment = new GroupFragment();
break;
case 1:
fragment = new AttendanceFragment();
break;
case 2:
fragment = new StatisticsFragment();
break;
}
return fragment;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
@Override
public int getCount() {
return TAB_TITLES.length;
}
}
Ошибка:
java.lang.ClassCastException: com.example.attendencetaker.MainActivity@26602bcMust implement AddGroupDialogListener
Я надеюсь, что мое объяснение проблемы понятно. Спасибо!
Комментарии:
1. Измените
listener = (AddGroupDialogListener) context;
наlistener = (AddGroupDialogListener) getParentFragment();
. Возможно, вы также захотите изменитьcontext.toString()
наgetParentFragment().toString()
дляClassCastException
сообщения.2. Я думаю, это могло бы сработать, но теперь он говорит, что прослушиватель равен null.
3. @MikeM. dialog не является дочерним элементом GroupFragment, поэтому метод getParentFragment возвращает нулевое значение.
4. Есть какие-либо предложения?
5. Извините, я неправильно прочитал часть вашего кода. Также измените
dialog.show(getFragmentManager(), ...);
строку, чтобы использоватьgetChildFragmentManager()
вместо.
Ответ №1:
Заставьте activity реализовать ваши интерфейсы и так далее, А затем передайте все данные во фрагмент с помощью метода для фрагмента. Вам понадобится ссылка на фактический отображаемый фрагмент.
В вашем фрагменте добавьте метод, аналогичный этому:
public void updateData(String data) {
editText.setText(data);
}
И в методе переопределения интерфейса в вашей деятельности для этого:
@Override
public void update(String data) {
fragment.updateData(data);
}
Обновить
Используйте этот адаптер вместо:
public class SectionTabAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments = new ArrayList<>();
private ArrayList<String> titles = new ArrayList<>();
public SectionTabAdapter(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
public void addFragment(Fragment fragment, String title) {
fragments.add(fragment);
titles.add(title);
}
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
Затем в вашей деятельности сделайте это:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionTabAdapter = new SectionTabAdapter(this, getSupportFragmentManager());
Fragment groupFragment = new GroupFragment();
Fragment attendanceFragment = new AttendanceFragment();
Fragment statisticsFragment = new StatisticsFragment();
sectionTabAdapter.addFragment(groupFragment, context.getString(R.string.title_1);
sectionTabAdapter.addFragment(attendanceFragment, context.getString(R.string.title_2);
sectionTabAdapter.addFragment(statisticsFragment, context.getString(R.string.title_3);
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionTabAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
Комментарии:
1. Я знаю это, но мне нужно использовать GroupFragment, чтобы изменить его пользовательский интерфейс.
2. первый метод используется в вашем фрагменте, второй — в вашей деятельности. Где-то вы создаете свой фрагмент, там вам нужно сохранить ссылку на него, и для этого вы вызываете метод, как показано во втором методе
3. Это могло бы решить проблему, знайте, что в состоянии witch (на чем-то) Я могу это сделать?
4. пока объект fragment существует и представление было создано, вы можете вызывать метод. но если вы не уверены, просто оберните внутреннюю часть метода one в try-catch
5. Как сохранить объект fragment? Я попробовал это в onCreate внутри MainActivity:
groupFragment = (GroupFragment) sectionsPagerAdapter.getItem(0); attendanceFragment = (AttendanceFragment) sectionsPagerAdapter.getItem(1); statisticsFragment = (StatisticsFragment) sectionsPagerAdapter.getItem(2);