BottomSheetDialog/BottomSheetDialogFragment - что использовать и как?

Я работаю над приложением Material design. Одна функция, которую я хочу реализовать, - это какой-то опрос. Когда пользователь нажимает на элемент списка, появляется диалог с постоянным нижним листом, который выглядит как this. Затем, когда пользователь нажимает на любую кнопку, этот диалог должен исчезнуть, и появится диалоговое окно модального нижнего листа, предоставляющее пользователю дополнительную информацию о элементе списка, который был нажат в начале. Это выглядит как this.

Я не могу найти никаких ясных объяснений о BottomSheetDialog и BottomSheetDialogFragment и о том, как правильно их использовать, даже прочитав некоторую информацию о диалоговом окне AppCompat. Итак, мои вопросы:

  • В какой форме они различны и какой из них я должен использовать для каждого случай?
  • Как получить данные в активности о том, какая кнопка была нажата в диалоговом окне?
  • Любые ссылки на код реализации или учебники об их использовании?

Ответ 1

Наконец, я нашел решение, и оно работает. Скажи мне, если я делаю что-то неправильно. В основном это работает как DialogFragment от это руководство, но я сделал это немного иначе.

1) Их разница такая же, как у DialogFragment и Dialog, и оба они модальные. Если вам нужен постоянный диалог, используйте BottomSheetBehaviour вместо (я узнал, что оба диалога должны быть модальными в моем приложении).

2) Сначала я должен ответить на третий вопрос с помощью некоторого кода, и тогда будет легко ответить на второй.

3) Создайте новый public class, который extends BottomSheetDialogFragment, я назвал его FragmentRandomEventPoll. Здесь должны быть две вещи.

  • Метод переопределения onCreateView. Это почти то же самое, что и метод onCreate в действиях, за исключением того, что он возвращает вид, который должен раздуваться:

    // We will need it later
    private static String headerItem;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                 Bundle savedInstanceState) {
    
    View v = inflater.inflate(R.layout.fragment_random_event_poll, container, false);
        header = (TextView) v.findViewById(R.id.uRnd_fragment_bottom_sheet_poll_header);
        skip = (Button) v.findViewById(R.id.uRnd_fragment_bottom_sheet_button_skip);
        header.setText(...);
    
        // I implemented View.OnClickListener interface in my class
        skip.setOnClickListener(this);
        return v;
    }
    
  • Статический метод, с помощью которого вы можете передать необходимые данные и получить новый экземпляр этого класса (возможно, я мог бы использовать обычный конструктор, мне придется поэкспериментировать с ним немного больше). URandomEventListItem - класс модели данных.

    public static FragmentRandomEventPoll newInstance(URandomEventListItem item) {
        FragmentRandomEventPoll fragment = new FragmentRandomEventPoll();
        headerItem = item.getHeader();
        return fragment;
    } 
    

2) Чтобы получить входные события в действии или в любом другом месте, определите интерфейс с необходимыми методами и создайте метод установки для экземпляра:

private PollButtonClickListener listener;

public void setListener(PollButtonClickListener listener) {
    this.listener = listener;
}

public interface PollButtonClickListener {
    void onAnyButtonClick(Object data)
}

И в том месте, где вы хотите получить свои данные (тег "dialog_event_poll" был указан в макете):

FragmentRandomEventPoll poll = FragmentRandomEventPoll.newInstance(events.get(id));
poll.setListener(new FragmentRandomEventPoll.PollButtonClickListener() {
        @Override
        public void onAnyButtonClick(Object data) {
            // Do what you want with your data
        }
    });
    poll.show(getSupportFragmentManager(), "dialog_event_poll");
}

Если что-то неясно, мои файлы проекта можно найти на Github.