已弃用ProgressDialog。备选方案是什么?

我偶然发现ProgressDialog现在已弃用。除了ProgressBar之外,还可以用什么来代替它。 我使用的是android studio 2.3.3版。< / p >

ProgressDialog progressDialog=new ProgressDialog(this);
progressDialog.show();
247333 次浏览

ProgressBar是ProgressDialog的最佳替代方案。 指示操作进度的用户界面元素

有关更多信息,请参阅谷歌文档: https://developer.android.com/reference/android/widget/ProgressBar.html

正如在文档页面中提到的,替代 ProgressBarProgressDialog的外观可以通过将ProgressBar放入AlertDialog中来复制。

你仍然可以使用它,但Android不希望你使用它,这就是它被弃用的原因。所以你应该考虑用另一种方式解决你的问题,比如将ProgressBar嵌入到你的Layout中。

这个类在API级别26中已弃用。ProgressDialog是一个模式 对话框,这会阻止用户与应用程序进行交互 使用这个类时,您应该使用一个进度指示器 ProgressBar,它可以嵌入到你的应用的UI中。另外, 您可以使用通知通知用户任务的进度。链接 < / p >

它在Android O被弃用,因为Google新的UI标准

也许这个指南可以帮助你。

通常我更喜欢用指示器制作自定义alertdialog。它解决了诸如自定义App视图等问题。

是的,在API level 26中它已弃用。相反,你可以使用progressBar

以编程方式创建:

首先获取根布局的引用

RelativeLayout layout = findViewById(R.id.display);  //specify here Root layout Id

RelativeLayout layout = findViewById(this);

然后添加进度条

progressBar = new ProgressBar(youractivity.this, null, android.R.attr.progressBarStyleLarge);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100, 100);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
layout.addView(progressBar, params);

显示进度条

progressBar.setVisibility(View.VISIBLE);

隐藏进度条

progressBar.setVisibility(View.GONE);
要禁用用户交互,您只需要添加以下内容 代码< / p >
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

为了恢复用户交互,您只需要添加以下代码

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

仅供将来参考,将android.R.attr.progressBarStyleSmall更改为android.R.attr.progressBarStyleHorizontal

下面的代码只适用于API level 21以上

progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));

通过xml创建:

<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:max="100"
android:backgroundTint="@color/white"
android:layout_below="@+id/framelauout"
android:indeterminateTint="#1a09d6"
android:layout_marginTop="-7dp"/>

在你的活动中

progressBar = (ProgressBar) findViewById(R.id.progressbar);

显示/隐藏进度条是一样的

 progressBar.setVisibility(View.VISIBLE); // To show the ProgressBar
progressBar.setVisibility(View.INVISIBLE); // To hide the ProgressBar

下面是它的样例图像:

 ></a></p>


<p>更多详细信息:<br>
<a href=1. 引用一个 < br > 2. 引用两个 < / p >

如果你真的想违背他们的意愿,你仍然可以使用甜蜜警报对话框或自己创建一个。

progress_dialog_layout


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


<TableRow
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="64dp" >


<ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent" />


<TextView
android:gravity="center|left"
android:id="@+id/textView9"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/black"
android:textSize="18sp"
android:text="Downloading data. Please wait.." />
</TableRow>
</RelativeLayout>

Java代码:

AlertDialog b;
AlertDialog.Builder dialogBuilder;


public void ShowProgressDialog() {
dialogBuilder = new AlertDialog.Builder(DataDownloadActivity.this);
LayoutInflater inflater = (LayoutInflater) getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View dialogView = inflater.inflate(R.layout.progress_dialog_layout, null);
dialogBuilder.setView(dialogView);
dialogBuilder.setCancelable(false);
b = dialogBuilder.create();
b.show();
}


public void HideProgressDialog(){


b.dismiss();
}

它可能对其他人有帮助。

许多流行的应用程序都有不同的方法来显示任何事情的进展,如网络请求,文件加载等。加载旋转器不会显示已加载或剩余的内容有多少。从UI/UX的角度来看,有一段时间的不确定性是不好的。许多流行的应用程序(Facebook, Linkedin等)通过首先显示基本的UI显示来解决这个问题。然后加载的内容逐渐填充在屏幕上。

我已经为我的应用程序使用微光来解决这个问题。

有一个很好的文章关于这将是有益的其他人

我使用https://github.com/Q115/DelayedProgressDialog中的DelayedProgressDialog,它的作用与ProgressDialog相同,但在必要时增加了延迟的好处。

使用它类似于Android O之前的ProgressDialog:

DelayedProgressDialog progressDialog = new DelayedProgressDialog();
progressDialog.show(getSupportFragmentManager(), "tag");

< >强ProgressDialog < / >强在API级别26中已弃用。

< >强"Deprecated" < / >强指的是正在被更新的函数或元素替换的函数或元素。

ProgressDialog是一个模态对话框,它阻止用户与之交互 而不是使用这个类,你应该使用一个进度 指示器,如< >强ProgressBar < / >强,它可以嵌入到你的应用程序的 UI。< / p >

优势

我个人认为ProgressBar比这两者更有优势。ProgressBar是一个用户界面元素,指示操作的进度。以不会产生中断方式向用户显示进度条。在应用程序的用户界面中显示进度条。

您可以简单地为progressbar设计一个xml接口,并将其作为一个视图传递给AlertDialog,然后在任何您需要的时候显示或关闭该对话框。

progress.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:padding="13dp"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">


<ProgressBar
android:id="@+id/loader"
android:layout_marginEnd="5dp"
android:layout_width="45dp"
android:layout_height="45dp" />
<TextView
android:layout_width="wrap_content"
android:text="Loading..."
android:textAppearance="?android:textAppearanceSmall"
android:layout_gravity="center_vertical"
android:id="@+id/loading_msg"
android:layout_toEndOf="@+id/loader"
android:layout_height="wrap_content" />


</LinearLayout>

显示进度对话框的代码代码。只需复制这段代码并粘贴它的片段。

Dialog dialog;


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);




AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(R.layout.progress);
// This should be called once in your Fragment's onViewCreated() or in Activity onCreate() method to avoid dialog duplicates.
dialog = builder.create();
}
    

//   This method is used to control the progress dialog.
private void setDialog(boolean show){
if (show)dialog.show();
else dialog.dismiss();
}

然后只要在你想要显示progressdialog时调用这个方法,并将true作为参数来显示它,或将false作为参数来取消对话框。

你可以使用wasabeef库来使用SpotDialog,你可以从下面的链接找到完整的教程:

Android spot dialog示例

你可以使用AlertDialog作为ProgressDialog参考下面的ProgressDialog代码。无论何时显示进度对话框,都需要调用此函数。

代码:

    public void setProgressDialog() {


int llPadding = 30;
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.setPadding(llPadding, llPadding, llPadding, llPadding);
ll.setGravity(Gravity.CENTER);
LinearLayout.LayoutParams llParam = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
llParam.gravity = Gravity.CENTER;
ll.setLayoutParams(llParam);


ProgressBar progressBar = new ProgressBar(this);
progressBar.setIndeterminate(true);
progressBar.setPadding(0, 0, llPadding, 0);
progressBar.setLayoutParams(llParam);


llParam = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
llParam.gravity = Gravity.CENTER;
TextView tvText = new TextView(this);
tvText.setText("Loading ...");
tvText.setTextColor(Color.parseColor("#000000"));
tvText.setTextSize(20);
tvText.setLayoutParams(llParam);


ll.addView(progressBar);
ll.addView(tvText);


AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setView(ll);


AlertDialog dialog = builder.create();
dialog.show();
Window window = dialog.getWindow();
if (window != null) {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.copyFrom(dialog.getWindow().getAttributes());
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
dialog.getWindow().setAttributes(layoutParams);
}
}

输出:

enter image description here

你可以使用我写的。它只提供最基本的服务 功能。如果你想要一个功能完整的ProgressDialog,那么使用 这个轻量级图书馆.

Gradle设置

在module/build.gradle中添加以下依赖项:

compile 'com.lmntrx.android.library.livin.missme:missme:0.1.5'

如何使用它?

用法类似于原始的ProgressDialog

ProgressDialog progressDialog = new
progressDialog(YourActivity.this);
progressDialog.setMessage("Please wait");
progressDialog.setCancelable(false);
progressDialog.show();
progressDialog.dismiss();

:必须覆盖活动的onBackPressed()

Java8实现:

@Override
public void onBackPressed() {
progressDialog.onBackPressed(
() -> {
super.onBackPressed();
return null;
}
);
}

芬兰湾的科特林实现:

override fun onBackPressed() {
progressDialog.onBackPressed { super.onBackPressed() }
}

是的,ProgressDialog已弃用,但Dialog没有。

你可以将自己的XML文件(包含进度条和加载文本)膨胀到对话框对象中,然后使用show()dismiss()函数显示或隐藏它。 下面是一个例子(Kotlin):

ProgressDialog类:

class ProgressDialog {
companion object {
fun progressDialog(context: Context): Dialog{
val dialog = Dialog(context)
val inflate = LayoutInflater.from(context).inflate(R.layout.progress_dialog, null)
dialog.setContentView(inflate)
dialog.setCancelable(false)
dialog.window!!.setBackgroundDrawable(
ColorDrawable(Color.TRANSPARENT))
return dialog
}
}
}

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:background="#fff"
android:padding="13dp"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="100dp"
android:layout_margin="7dp"
android:layout_height="100dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="7dp"
android:layout_toEndOf="@+id/progressBar"
android:text="Loading..." />
</RelativeLayout>
< p > 在代码中: 只需执行var dialog = ProgressDialog.progressDialog(context)

要显示:dialog.show()

隐藏:dialog.dismiss()

ProgressBar是非常简单和容易使用, 我打算制作一个同样简单的进度对话框。 第一步是你可以为你想要显示的对话框创建XML布局,假设我们将这个布局命名为

layout_loading_dialog.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="20dp">
<ProgressBar
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />


<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="4"
android:gravity="center"
android:text="Please wait! This may take a moment." />
</LinearLayout>

下一步是创建AlertDialog,它将用ProgressBar显示这个布局

AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(false); // if you want user to wait for some process to finish,
builder.setView(R.layout.layout_loading_dialog);
AlertDialog dialog = builder.create();
现在剩下的就是在点击事件中显示和隐藏这个对话框 这样的< / p >
dialog.show(); // to show this dialog
dialog.dismiss(); // to hide this dialog

,这就是它,它应该工作,因为你可以看到它是相当简单和容易实现的ProgressBar而不是ProgressDialog。 现在你可以在Handler或ASyncTask中显示/取消这个对话框,这取决于你的需要

在进度对话框中,用户不能做任何工作。所有后台进程在进度对话框中停止。因此,建议使用进度条代替进度对话框。

您不需要导入任何自定义库。

我更喜欢使用现代的AlertDialog,所以这是联合国开发峡谷在本页中发布的伟大答案的芬兰湾的科特林版本。

芬兰湾的科特林代码:

fun setProgressDialog(context:Context, message:String):AlertDialog {
val llPadding = 30
val ll = LinearLayout(context)
ll.orientation = LinearLayout.HORIZONTAL
ll.setPadding(llPadding, llPadding, llPadding, llPadding)
ll.gravity = Gravity.CENTER
var llParam = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT)
llParam.gravity = Gravity.CENTER
ll.layoutParams = llParam


val progressBar = ProgressBar(context)
progressBar.isIndeterminate = true
progressBar.setPadding(0, 0, llPadding, 0)
progressBar.layoutParams = llParam


llParam = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
llParam.gravity = Gravity.CENTER
val tvText = TextView(context)
tvText.text = message
tvText.setTextColor(Color.parseColor("#000000"))
tvText.textSize = 20.toFloat()
tvText.layoutParams = llParam


ll.addView(progressBar)
ll.addView(tvText)


val builder = AlertDialog.Builder(context)
builder.setCancelable(true)
builder.setView(ll)


val dialog = builder.create()
val window = dialog.window
if (window != null) {
val layoutParams = WindowManager.LayoutParams()
layoutParams.copyFrom(dialog.window?.attributes)
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT
layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT
dialog.window?.attributes = layoutParams
}
return dialog
}

用法:

val dialog = setProgressDialog(this, "Loading..")
dialog.show()

输出:

enter image description here

下面是我的不确定进度对话框版本:

layout_loading_dialog.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:padding="20dp">


<ProgressBar
android:id="@+id/progressBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1" />


<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="4"
android:gravity="center"
android:textAlignment="textStart"
android:id="@+id/message"
tools:text="Please wait..." />
</LinearLayout>

IndeterminateProgressDialog.kt:

class IndeterminateProgressDialog(context: Context) : AlertDialog(context) {
private val messageTextView: TextView


init {
val view = LayoutInflater.from(context).inflate(R.layout.layout_loading_dialog, null)
messageTextView = view.findViewById(R.id.message)
setView(view)
}


override fun setMessage(message: CharSequence?) {
this.messageTextView.text = message.toString()
}


}

用法:

   val dialog = IndeterminateProgressDialog(context)
dialog.setMessage("Please wait...")
dialog.setCanceledOnTouchOutside(false)
dialog.setCancelable(false)
dialog.show()

使用这个简单的技巧

/ /初始化

val dialog : Dialog = Dialog(this)

/ /设置布局

dialog.setContentView(R.layout.view_loading)

/ /显示对话框

dialog.show()

//删除白色背景

dialog.window.setbackgroundDrawable(ColorDrawable(0))

下面是@Han建议的ProgressDialog类的kotlin版本

class ProgressDialog(context: Context) : Dialog(context) {
init {
val view = View.inflate(context, R.layout.progress_dialog, null)
setContentView(view)
setCancelable(false)
window?.setBackgroundDrawable(
ColorDrawable(Color.TRANSPARENT)
)
}

创建一个带有进度条和其他视图的xml文件,并使用此xml文件或Alertdialog派生类扩展派生Dialog类视图。在其他解决方案中已详细提供。 但是如果你想要一个解或者存在的库。我找到了这两个

  1. < p > https://github.com/Livin21/MissMe

  2. < p > https://github.com/skydoves/ProgressView

这些都是完美的,而且是根据需要来做的。

Kotlin和androidx DialogFragment的另一个解决方案

通过使用DialogFragment,你不必每次都在需要显示对话框的每个屏幕上调整窗口的大小,我认为这是一个更干净的解决方案

  1. 创建对话框类

class BaseProgressDialog : DialogFragment() {


companion object {
const val DIALOG_TAG = "BaseProgressDialogFragment"
}


override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val builder = AlertDialog.Builder(it, R.style.MainAlertDialog)
val inflater = requireActivity().layoutInflater
val dialogView = inflater.inflate(R.layout.progress_dialog, null)


builder.setView(dialogView)
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}


override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
dialog?.setCanceledOnTouchOutside(false)
dialog?.setCancelable(false)
return super.onCreateView(inflater, container, savedInstanceState)
}


override fun onResume() {
super.onResume()
val size = resources.getDimensionPixelSize(R.dimen.size_80dp)
dialog?.window?.setLayout(size, size)
}
}
  1. styles.xml中创建样式
<style name="MainAlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:windowBackground">@drawable/bg_alert_dialog</item>
</style>
  1. 为你的对话bg_alert_dialog.xml创建背景
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/colorSecondary"/>
<corners android:radius="@dimen/radius_10dp" />
</shape>
  1. 为对话框progress_dialog.xml创建布局
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_alert_dialog"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/padding_16dp">


<com.google.android.material.progressindicator.CircularProgressIndicator
android:layout_width="@dimen/size_40dp"
android:layout_height="@dimen/size_40dp"
android:indeterminate="true"
app:indicatorColor="?attr/colorPrimary" />


</LinearLayout>
  1. 调用片段中的对话框
private var progressDialog = BaseProgressDialog()
activity?.let {
progressDialog.show(it.supportFragmentManager, BaseProgressDialog.DIALOG_TAG)
}

这是它看起来的样子:

enter image description here