【问题标题】:How to add custom button to material date range picker android?如何将自定义按钮添加到材料日期范围选择器android?
【发布时间】:2022-01-13 15:45:36
【问题描述】:

如何向材料日期范围选择器添加自定义按钮?

我正在尝试查看对话框以便以编程方式添加按钮,但我无法从选择器中获得任何视图。

        MaterialDatePicker.Builder<Pair<Long,Long>> builder = MaterialDatePicker.Builder.dateRangePicker();
        MaterialDatePicker<Pair<Long,Long>> materialDatePicker = builder
            .setTitleText("Select Dates")
            .build();
        dateRangeTV.setOnClickListener(v -> {
            materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER");
            View root = materialDatePicker.requireView();
        });

但我说错了。

java.lang.IllegalStateException: Fragment MaterialDatePicker{e52ecfc} (40593b4f-a55a-4d6c-aa3b-2b778e721149 tag=DATE_PICKER) did not return a View from onCreateView() or this was called before onCreateView().

【问题讨论】:

    标签: android material-components-android


    【解决方案1】:

    发生此错误是因为 materialDatePicker.show() 是一个异步调用,并且尚未创建 MaterialDatePicker (DialogFragment) 以便能够访问其根视图。为避免此错误,您必须通过添加DefaultLifecycleObserver 来使用materialDatePicker.getLifecycle() 监听DialogFragment Lifecycle,并使用覆盖方法void onStart(@NonNull LifecycleOwner owner) 从那里访问MaterialDatePicker 根视图。

    将您的代码更改为如下所示:

    MaterialDatePicker.Builder<Pair<Long,Long>> builder = MaterialDatePicker.Builder.dateRangePicker();
    MaterialDatePicker<Pair<Long,Long>> materialDatePicker = builder
            .setTitleText("Select Dates")
            .build();
    materialDatePicker.getLifecycle().addObserver(new DefaultLifecycleObserver()
    {
        @Override
        public void onCreate(@NonNull LifecycleOwner owner) {}
    
        @Override
        public void onStart(@NonNull LifecycleOwner owner) {
            //in onStart of DialogFragment the View has been created so you can access the materialDatePicker.requireView()
            View root = materialDatePicker.requireView();
            //from root find the View you are interested to add your custom button
        }
    
        @Override
        public void onResume(@NonNull LifecycleOwner owner) {}
    
        @Override
        public void onDestroy(@NonNull LifecycleOwner owner) {
            //remove Lifecycle Observer
            materialDatePicker.getLifecycle().removeObserver(this);
        }
    });
    materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER");
    

    【讨论】:

      【解决方案2】:

      在此示例中,我创建了一个类 MainActivity.java,它的布局从 Button 打开自定义对话框,如下所示:

      MainActivity.java

      public class MainActivity extends AppCompatActivity {
      
          private static final String TAG = "MainActivity";
      
          private Button openDialog;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              openDialog = findViewById(R.id.open_dialog);
              openDialog.setOnClickListener(v -> {
                  Log.d(TAG, "onClick: opening dialog.");
                  MyCustomDialog dialog = new MyCustomDialog();
                  dialog.show(getSupportFragmentManager(), "MyCustomDialog");
              });
          }
      }
      

      LayoutButton activity_main.xml:

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context="MainActivity">
      
          <Button
              android:id="@+id/open_dialog"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerInParent="true"
              android:layout_centerHorizontal="true"
              android:layout_marginTop="20sp"
              android:text="open dialog" />
      
      </RelativeLayout>
      

      MyCustomDialog.java 类扩展了DialogFragment 以拥有一个自定义视图来存储DatePicker 和其他Widgets。 (例如TextView):

      public class MyCustomDialog extends DialogFragment {
      
          private static final String TAG = "MyCustomDialog";
      
          private TextView mActionOk, mActionCancel;
      
          @Nullable
          @Override
          public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
              View view = inflater.inflate(R.layout.dialog_my_custom, container, false);
              mActionCancel = view.findViewById(R.id.action_cancel);
              mActionOk = view.findViewById(R.id.action_ok);
      
              mActionCancel.setOnClickListener(v -> {
                  Log.d(TAG, "onClick: closing dialog");
                  getDialog().dismiss();
              });
      
              mActionOk.setOnClickListener(v -> {
                  Log.d(TAG, "onClick: capturing input");
                  getDialog().dismiss();
              });
      
              return view;
          }
      }
      

      最后但同样重要的是XML 文件dialog_my_custom.xml

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context=".MainActivity">
      
          <RelativeLayout
              android:layout_width="match_parent"
              android:layout_height="550dp"
              android:padding="10dp">
      
              <TextView
                  android:id="@+id/heading"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_marginBottom="20dp"
                  android:text="This is your custom View with DatePicker"
                  android:textAlignment="center"
                  android:textColor="#000"
                  android:textSize="18sp" />
      
              <DatePicker
                  android:id="@+id/date_picker"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_below="@+id/heading"
                  android:layout_centerHorizontal="true" />
      
              <RelativeLayout
                  android:id="@+id/frame"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_below="@+id/date_picker">
      
                  <TextView
                      android:id="@+id/action_ok"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:layout_alignParentRight="true"
                      android:layout_alignParentBottom="true"
                      android:layout_marginRight="20dp"
                      android:text="OK"
                      android:textColor="#33bbff"
                      android:textSize="18sp" />
      
                  <TextView
                      android:id="@+id/action_cancel"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:layout_alignParentLeft="true"
                      android:layout_alignParentBottom="true"
                      android:layout_marginRight="20dp"
                      android:text="CANCEL"
                      android:textColor="#33bbff"
                      android:textSize="18sp" />
              </RelativeLayout>
          </RelativeLayout>
      </RelativeLayout>
      

      不要忘记添加支持库的dependency

      implementation  "com.android.support:appcompat-v7:$supportLibVersion"
      

      结果:

      【讨论】:

      • 抱歉,我想查看日期选择器本人。
      • 编辑了我的答案。给你 :) 现在你有你的自定义视图。希望我能帮助你。随意将答案标记为正确且最重要的快乐编码! :)
      • 我可以在这个自定义片段中获取材料日期范围选择器吗?
      • 你想在什么视图下拥有这个?您的 DatePicker 已经在您的自定义视图中。你用了我的源代码吗?都已经装好了。
      猜你喜欢
      • 2023-02-17
      • 1970-01-01
      • 1970-01-01
      • 2016-02-12
      • 2020-04-03
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多