简体   繁体   中英

creating a Custom Dialog with DialogFragment

I've found several supposedly working examples, each is little bit different from the other, but whichever I tried to implement I get the same compiler error. Here's code for the DialogFragment . No problem reported here.

EDIT: I actually had coded Custom DialogFragment in my code after I had posted. That WOULD be a problem, but it actually wasn't. I apologize.

public class Custom DialogFragment extends DialogFragment

    {
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                               Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_sample_dialog, container, false);
            getDialog().setTitle("dialog");
            return v;
        }
    }

}

I've made btn static . No difference. I've moved the code out of onClick into onCreate . No difference. Made my activity extend FragmentActivity . No matter what I do, I get this error on the line with ****** below:

cannot resolve method 'show(android.app.FragmentManager, java.lang.String)'

code for the Activity :

public class CustomDialogActivity extends Activity
{
  Button btn ;
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_sample_dialog);
    btn = new Button(this);
    btn = findViewById(R.id.dismiss);
    btn.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View v)
      {
        FragmentManager fm = getFragmentManager();
        CustomDialogFragment dialogFragment = new CustomDialogFragment();
        dialogFragment.show(fm, "Sample Fragment"); // **********     
      }
    });
  }
}

What should I do? Most of the code comes from one web page or another or the other. You'd think I could get it to run.

If I remove Custom from both sides of the statement above the ******, it compiles, but then it's not MY CustomDialog anymore and no dialog shows anyway. (If I remove Custom from just one side, I get compiler error. Casting fails.)

If I use getSupportFragmentManager() in place of fm in the line with ******, there's no error, but no dialog pops up.

I'm obviously lost.


PS Here's build.gradle for app ; xml follows, but surely it's not the problem:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.dslomer64.customdialogactivity"
        minSdkVersion 23
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
           minifyEnabled false
           proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

simple_dialog_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:padding="10dp"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/image" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Lorem ipsum dolor sit amet..."
        android:textSize="20dp" />

    <Button
        android:id="@+id/dismiss"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Dismiss" />
</LinearLayout>

I did what I should have done long ago: read completely through and took notes on "everything" there is to know about Dialog coding, with great examples and looked for tips and took notes at Dialog design do's and dont's , where there's also a lot of info about Theming at the end. Questions about Dialog ? Go there.

Only 3 lines of executable DialogFragment statements is a bit lean. For one thing, it had no overridden onCreateDialog method. And putting onClick in the Activity wasn't a good idea since it referred to a Fragment that hadn't even been created and since the action takes place in the Fragment .

And as @Commonsware pointed out, I should have been using the Support Library versions of Activity and Fragment .

So, here's what the activity should have been:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class CustomDialogActivity extends AppCompatActivity
{
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_sample_dialog);
    CustomDialogFragment cdf = new CustomDialogFragment();
    cdf.show(getSupportFragmentManager(),"Showing dialog");
  }
}

And here's the dialog fragment. I wish I could say it's all my code, but I got it all from one example or other at the first link above. But sometimes it's just what ya do:

import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

...

public class CustomDialogFragment extends android.support.v4.app.DialogFragment
{
  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  {
    View rootView = inflater.inflate(R.layout.fragment_sample_dialog, container,false);
    getDialog().setTitle("Simple Dialog");
    return rootView;
  }

  @Override public Dialog onCreateDialog(Bundle savedInstanceState)
  {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle("Simple Dialog");
    builder.setMessage("Hey, a dialog!");

    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
    {
      @Override public void onClick(DialogInterface dialog, int which)
      {
        Toast.makeText(getContext(), R.string.fire, Toast.LENGTH_LONG).show();
        dismiss();
      }
    });

    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
    {
      @Override public void onClick(DialogInterface dialog, int which)
      {
        Toast.makeText(getContext(), R.string.cancel, Toast.LENGTH_LONG).show();
        dismiss();
      }
    });
    return builder.create();
  }
}

First, your fragment is named MyDialogFragment . You are trying to show CustomDialogFragment . Those are not the same. From the code snippets in your question, it would appear that you have nothing named CustomDialogFragment .

Once you fix that, you need to ensure that you are using the same fragment system consistently. Given that native fragments are deprecated in Android 9.0+, for new development, you should be using a library edition of fragments. That would involve:

  • Having your activity extend from FragmentActivity or from something else that extends FragmentActivity , such as AppCompatActivity

  • Having your fragment extend from android.support.v4.app.DialogFragment

  • Using getSupportFragmentManager()

(note: I am using Android Support Library package names in this answer — substitute with androidx editions if you are using AndroidX)

Here is a simple working code to demonstrate DialogFragment

MyDialogFragment.java

import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;

public class MyDialogFragment extends DialogFragment {

    Activity activity = null;

    public static MyDialogFragment createInstance(Activity activity) {

        MyDialogFragment fragment = new MyDialogFragment();
        fragment.activity = activity;
        return fragment;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        View view = activity.getLayoutInflater().inflate(R.layout.my_custom_dialog_layout, null);

        DisplayMetrics displayMetrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        double height = displayMetrics.heightPixels * 0.9;
        double width = displayMetrics.widthPixels * 0.9;

        Dialog dialog = new Dialog(getActivity(), R.style.custom_theme);
        dialog.setTitle("Title Text");
        dialog.setContentView(view);
        dialog.show();
        dialog.getWindow().setLayout((int) width, (int) height);
        dialog.setCanceledOnTouchOutside(true);
        return dialog;
    }
}

my_custom_dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

     ...

</LinearLayout>

styles.xml

<resources>
     ...
     ...
   <style name="custom_theme">
      <item name="android:windowIsFloating">true</item>
      <item name="android:windowBackground">@android:color/white</item>
   </style>
</resources>

Now, simply add below line to call and show DialogFragment.

MyDialogFragment.createInstance(activity).show(activity.getFragmentManager(), "TAG");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM