Как создать пользовательский AlertDialog из фрагмента с вкладками?

#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);