【问题标题】:Dialog pops up very slow对话框弹出很慢
【发布时间】:2020-08-07 07:18:59
【问题描述】:

在我的应用程序中,我通过扩展 DialogFragment 实现了this 自定义对话框(具有相当复杂的布局)。我希望当我单击布局中的按钮时会弹出此对话框。 (我已经成功实现)。但问题是对话框以一种不流畅的方式显示。

我的自定义对话框类:

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 类:

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();
    }
}

如果您需要对话框的布局代码,请在 cmets 中告诉我。

我尝试了什么:

  1. 实现线程,以便我的对话框在后台线程中准备好并在ButtonClick 上显示。但这通常是不允许的,因为除了 UI 线程之外的任何其他线程都不应该接触 UI 相关事件。
  2. 使用 onCreateView 代替 onCreateDialog 直接膨胀布局。
  3. 将对话框设为全局变量,在 onCreate 中对其进行初始化,然后在 onButtonClick 中显示对话框。
  4. 切换到约束布局
  5. 通过将对话框主题设置为清单文件中的活动,将活动用作对话框。
  6. 在比我的硬件更好的设备上启动我的应用程序。 但没有任何效果

我想要什么:

为什么我的对话框卡顿?以及我需要做什么才能使对话框弹出得更快?

如果有人想要 here 的链接到我在 github 上的应用程序仓库。

【问题讨论】:

    标签: android performance dialog


    【解决方案1】:

    AlertDialogDialogFragment 框架很慢,因为它们需要一些时间来进行计算和碎片化的东西。所以解决这个问题的方法是,直接使用 Dialog 框架。

    1. 使用 Dialog 框架的构造函数来初始化一个对话框对象,如下所示:

      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. 定义布局,然后使用dialog.setContentView(R.layout.name_of_layout)

    3. 使用dialog.findViewById(R.id.name_of_view) 引用对话框布局文件中的视图

    然后像任何人在活动类中那样实现逻辑。阅读官方documentation,找出最适合您用例的实现。

    【讨论】:

      猜你喜欢
      • 2015-09-17
      • 2012-06-07
      • 2012-02-05
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多