Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
154 views
in Technique[技术] by (71.8m points)

android - Dialog pops up very slow

In my app I have implemented this custom dialog (which has a fairly complex layout) by extending DialogFragment. I expect this dialog to pop up when I click a button in my layout. (Which I have successfully achieved). But the problem is that the dialog shows up in a janky manner.

My custom dialog class:

public class CustomizeDialog extends DialogFragment implements AdapterView.OnItemSelectedListener {
    // field declarations go here
    @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.customize_dialog, null);

        builder.setView(view)
                .setTitle("Customize")
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .setPositiveButton("Let's go!", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent();
                        intent.setAction("fromDialog");
                        intent.putExtra("ratio",getRatio(paperSizeSpinner.getSelectedItem().toString()));
                        if(isOrientationSpinnerVisible){
                            intent.putExtra("isCustom",false);
                            intent.putExtra("orientation",orientationSpinner.getSelectedItem().toString());
                        } else {
                            intent.putExtra("isCustom",true);
                        }
                        intentProvider.getIntent(intent);
                    }
                });

        widthEditText = view.findViewById(R.id.width_et);
        heightEditText = view.findViewById(R.id.height_et);

        widthEditText.setEnabled(false);
        heightEditText.setEnabled(false);

        paperSizeSpinner = view.findViewById(R.id.paper_size_spinner);
        orientationSpinner = view.findViewById(R.id.orientation_spinner);
        // ArrayList for populating paperSize spinner via paperSizeAdapter
        ArrayList<String> paperSizes = new ArrayList<>();
        paperSizes.add("A0");
        paperSizes.add("A1");
        paperSizes.add("A2");
        paperSizes.add("A3");
        paperSizes.add("A4");
        paperSizes.add("A5");
        paperSizes.add("Custom");
        // ArrayList for populating orientation spinner via orientationAdapter
        ArrayList<String> orientation = new ArrayList<>();
        orientation.add("Portrait");
        orientation.add("Landscape");
        // arrayAdapters containing arraylists to populate spinners
        ArrayAdapter paperSizeAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_spinner_dropdown_item, paperSizes);
        ArrayAdapter orientationAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_spinner_dropdown_item, orientation);
        paperSizeSpinner.setAdapter(paperSizeAdapter);
        orientationSpinner.setAdapter(orientationAdapter);

        paperSizeSpinner.setSelection(4);
        paperSizeSpinner.setOnItemSelectedListener(this);
        orientationSpinner.setOnItemSelectedListener(this);
        return builder.create();
    }

    // These are some important complex ui functionalities
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        if (parent.getId() == R.id.paper_size_spinner) {
            if (position == 6) {
                widthEditText.setEnabled(true);
                heightEditText.setEnabled(true);
                orientationSpinner.setEnabled(false);
                isOrientationSpinnerVisible = false;
            } else {
                widthEditText.setEnabled(false);
                heightEditText.setEnabled(false);
                orientationSpinner.setEnabled(true);
                isOrientationSpinnerVisible = true;
            }
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
    // interface used to communicate with the parent activity
    public interface IntentProvider {
        // this method is used to provide the intent to the parent activity
        void getIntent(Intent intent);
    }
    // instantiating the interface object and throwing error if parent activity does not implement this interface
    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        try {
            intentProvider = (IntentProvider) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement IntentProvider");
        }
    }

}

MainActivity class:

public class MainActivity extends AppCompatActivity implements CustomizeDialog.IntentProvider {
    // field declarations go here
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = findViewById(R.id.image);
        // instantiating the dialog
        final CustomizeDialog dialog = new CustomizeDialog();
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // showing the dialog on click
                dialog.show(getSupportFragmentManager(),"");
            }
        });

    }
    // via this method I receive the intent from the dialog
    // I know intent might not be the best option for this function but let's let it be here for now
    @Override
    public void getIntent(Intent intent) {
        ratio = intent.getFloatExtra("ratio",3);
        isCustom = intent.getBooleanExtra("isCustom",false);
        orientation = intent.getStringExtra("orientation");
        launchChooser();
    }
}

Let me know in the comments if you want the layout code for the dialog.

What I tried:

  1. Implementing threading so that my dialog is ready in a background thread and show it onButtonClick. But this is not allowed in general as any other thread except UI thread aren't supposed to touch UI related events.
  2. Using onCreateView instead of onCreateDialog to inflate the layout directly.
  3. Making the dialog a global variable, initialized it in onCreate and then show the dialog onButtonClick.
  4. Switched to CONSTRAINT LAYOUT
  5. Using an activity as a dialog by setting the dialog theme to the activity in the manifest file.
  6. Launched my app in a device with better hardware than mine. BUT NOTHING WORKED

What I want:

Why is my dialog janky? and what I need to do to make the dialog pop up faster?

In case anybody wants here's the link to my app repo on github.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

AlertDialog and DialogFragment frameworks are slow because they need to some time to do calculations and fragment stuffs. So a solution to this problem is, using the Dialog framework straight away.

  1. Use the Dialog framework's constructor to initialize a Dialog object like this:

    Dialog dialog = new Dialog(context, R.style.Theme_AppCompat_Dialog);
    // the second parameter is not compulsory and you can use other themes as well
    
  2. Define the layout and then use dialog.setContentView(R.layout.name_of_layout).

  3. Use dialog.findViewById(R.id.name_of_view) to reference views from the dialog's layout file

And then implement the logic just like anyone would do in an activity class. Find out the best implementation for your use case by reading the official documentation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...