dialog.show()报错

img


代码参考的是https://blog.csdn.net/qq_53932746/article/details/118793589?spm=1001.2014.3001.5502
为什么这个show函数报错
MainActivity.java


```java
package com.example.shiyan31;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.example.shiyan31.R;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private String a;//全局变量,记录点击哪一项
    private   ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.MyListView);
        List<String>list=new ArrayList<String>();
        list.add("张三");
        list.add("李四");
        list.add("狗子");
        list.add("小王");
        list.add("小红");
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,list);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                String mag =adapter.getItem(position);
                a = mag;
                final Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                intent.putExtra("name", mag.toString());
                startActivityForResult(intent, 1);
            }
        });}

    protected void onActivityResult(int requestCode,int resultCode, Intent data) {//requestCode 为父界面的编号
        //resultCode 为子界面的返回编号
        //data可以使传递的值
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == 2) {
            adapter.remove(a);
        }

    }
}


SecondActivity.java


```java
package com.example.shiyan31;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.example.shiyan31.R;

public class SecondActivity extends AppCompatActivity {
    private int index;

    private String name=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        final  Intent intent1;
        intent1=getIntent();
        name=intent1.getStringExtra("name");
        AlertDialog dialog=new AlertDialog.Builder(SecondActivity.this.getApplicationContext())
                .setMessage("删除"+name+"的记录吗?")
                .setNegativeButton("取消",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                finish();
                            }
                        })
                .setPositiveButton("确定",
                        new DialogInterface.OnClickListener() {
                            Intent intent=new Intent();
                            public void onClick(DialogInterface dialog, int which) {
                                setResult(2,intent);//设置子界面的编号并返回
                                finish();

                            }

                        })
                .create();
        dialog.show();
    }
}


activity_main.xml


```xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <ListView
        android:id="@+id/MyListView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbarSize="30sp"
        android:dividerHeight="5dp"
        android:headerDividersEnabled="true"/>

</LinearLayout>

activity_second.xml



```xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical">
</LinearLayout>

工程

img

build.gradle版本

img

这一页代码都贴上来吧

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/1764
  • 这篇博客也不错, 你可以看下dialog显示位置
  • 除此之外, 这篇博客: dialog设置动画及属性动画的部分说明中的 先说一下碰到的问题: 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    1. 怎么给dialog设置动画。
    2. 属性动画的说明。
    3. 动画在移动的时候,到了某个位置消失了。
    4. dialog在用户点击返回键的处理。

    下面是针对我的问题,一个个解决。

    • 设置动画

    一般我们在做dialog的时候,最常用的是设置dialog的进入和出去的动画,这个一般在onCreateDialog的时候,通过window去设置。就是下面的代码。

    Window window = dialog.getWindow();
    if (window != null) {
        window.setWindowAnimations(R.style.dialog_animation);
    }
    这里顺便带一句,如果要设置或者取消外部点击消失,用这个方法dialog.setCanceledOnTouchOutside(true);这个方法一般也是在onCreateDialog的时候设置就可以了。
    但是,通过设置style我们无法很精确的移动到我们需要的坐标位置,而且移动位置如果有一点变化,可能需要重新计算等问题。
    所以,我们需要在代码中,通过计算使动画移动的位置更准确。这个时候就需要思考怎么给整个dialog设置动画了。
    一开始我一直在考虑怎么给整个dialog设置动画,然后通过getdialog获取到dialog的对象以后,无法把animator设置给dialog,提示我说动画只能针对view设置。后来突然发现,思路进入牛角尖了,dialog的view不就是view嘛,然后我就直接通过getview或者可以通过获取dialog的最外层布局即可获取到需要设置动画的对象。到这里,我们的动画就有了思路。
    
    • 属性动画

    动画的选择方面,我这边使用的是属性动画ObjectAnimator。属性动画会直接改变控件的属性,即在动画完成以后,实际位置/大  小/透明度都发生了改变的,常用的属性动画有缩放/平移/渐变度的改变。这边稍微说明一下,详细可以百度属性动画自行了解。我们这次的需求只需要使用一个缩放 + 平移即可。

    ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(getView(), "scaleX",1, 0.1f); 
    说明一下这里的参数,第一个是需要做动画的view,第二个scaleX是针对x轴进行缩放,后面的参数是变化的值,如我这里,从原大小变成0.1倍的大小,当然你也可以从0 -> 1.0f 。你也可以设置(0.1f, 1.0f, 0.5f, 2.0f)这里可以传多个值。同理可以设置scaleY。针对Y进行变换。缩放动画就这几个。
    ObjectAnimator transXAnim = ObjectAnimator.ofFloat(getView(), "translationX",0, tranX);
    这个是平移动画,前2个参数相同。后面的参数说明一下,我使用的时候,也是很久没用了,最开始以为是从0的位置移动到tranX这个坐标,后来发现是向x轴移动tranX位置。所以我们需要计算,动画需要在x上移动的距离。
    int tranX = tranToX - tranStartX; (移动距离 = 目标位置x点坐标 - 当前位置x点坐标) 。然后把这个移动距离设置到动画数值那里即可,类似旋转的。当然也可以设置多个值,比如先右X移动100个距离,然后再向左移动200个位置,然后再向右移动50个位置。(getView(), "translationX",100, -200,50);(X移动时正为向右,负数为向左移动。同理Y轴移动的时候,正为向下,负数向上移动)其余就不过多介绍属性动画了,设置一个动画持续时间,设置一个动画循环的次数,通过.playTogether(动画A, 动画B); start()动画即可。
    
    突然想起来了,这里目标位置的坐标获取说明一下:目标位置一般都是移动到某个view上。我这边是通过下面这个方法
    int[] location = new int[2];
    mTargerView.getLocationInWindow(location);
    通过获取目标位置在屏幕中的位置,这样会比较准备。当然具体做动画的时候要根据移动的位置计算一下view的宽高。
    
    • 移动以后消失,动画的部分细节(这个是这里重点需要说明的)

    动画执行的时候碰到或者有跳动,或者有消失等等问题。对了,这里需要说一下,要把原来的dialog移除的时候的动画移除了,不然dialog在移除的时候还有一个动画,即最开始说的常用dialog进入和退出时的动画。最开始猜想可能是位置计算有错,我一开始是毛估估的计算了动画移动的位置,没有按照上面说的精确计算,这样可以解决动画跳动的问题。然后就是动画走到快要结束的地方有一个消失的情况,一开始也去考虑是不是位置算错了。后来多次验证发现和距离应该没关系,动画的移动距离没问题。我在没有调用dialog的dismiss方法时,动画执行到最后ui也消失了,后来突然想到,会不会和dialog的整体宽高有关。然后就修改了整个dialog为matchparent,再设置了一个透明的背景。重新执行动画,问题解决。那我这里就猜想,动画执行时,只能在view所绘制的区域内,超出了以后就会消失。

    • 返回键的处理

    最后把我们上面写的消失的动画设置到dialog的关闭按钮响应上即可。其余的就剩一些优化了,比如dialog销毁的时候动画的回收,dialog多次调用覆盖等问题。然后就是用户不去点击我们设置的关闭按钮,直接通过手机的返回按钮来关闭dialog,由于我们不是在dialog的dismiss()方法里面设置的动画,这就需要我们去设置dialog在点击返回按钮的回掉了。一开始我是对整个Activity的back事件进行判断,后来发现dialog自己有一个setOnKeyListener()的方法,通过重写里面的onKey方法,这样可以在dialog显示的时候监听到用户点击返回键。

    getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
                Log.e("xnm", "KEYCODE_BACK");
                showDismissScaleAnim();
                return true;
            }
            return false;
        }
    });
    一开始是没有增加(event.getAction() == KeyEvent.ACTION_UP)判断,然后在看日志的时候发现日志打印了两遍,后来突然想到了,可能是按下和抬起的事件都监听到了,然后增加了一个判断,解决两次回调的问题。
    

    好了,本期的分享到这里就结束了,谢谢大家,有问题请指正。