安卓如何在SnackBar上显示进度对话框?

9

有没有办法在使用AsyncTask进行分页获取数据时,在SnackBar上显示进度对话框。如果可能的话,如何实现,请给出建议。


尝试一下这个... https://github.com/tingyik90/snackprogressbar - sk sakil
5个回答

19

对于新设计库:

如果您想在左侧显示进度条:

 Snackbar bar = Snackbar.make(root, R.string.data_updating, Snackbar.LENGTH_INDEFINITE);
        ViewGroup contentLay = (ViewGroup) bar.getView().findViewById(android.support.design.R.id.snackbar_text).getParent();
        ProgressBar item = new ProgressBar(context);
        contentLay.addView(item,0);
        bar.show();

或者在右侧:

 Snackbar bar = Snackbar.make(root, R.string.data_updating, Snackbar.LENGTH_INDEFINITE);
        ViewGroup contentLay = (ViewGroup) bar.getView().findViewById(android.support.design.R.id.snackbar_text).getParent();
        ProgressBar item = new ProgressBar(context);
        contentLay.addView(item);
        bar.show();

13
2018年,如果你正在使用谷歌的新材料设计,则ID应为“com.google.android.material.R.id.snackbar_text”。 - Shababb Karim
调用 getParent() 两次:bar.getView().findViewById(com.google.android.material.R.id.snackbar_text).getParent().getParent() - Pat Lee

8
最简单且最好的方法是这样的:
Snackbar bar = Snackbar.make(layout, "Somthing", Snackbar.LENGTH_INDEFINITE);
Snackbar.SnackbarLayout snack_view = bar.getView();
snack_view.addView(new ProgressBar(context));
bar.show();

SnackbarLayout 继承 LinearLayout,因此您可以将视图添加为其子级或按照您想要的方式进行自定义。

例如,要更改 SnackBar 内部 TextView 的样式,您可以执行以下操作:

TextView tv = (TextView) bar.getView().findViewById(android.support.design.R.id.snackbar_text);
tv.setTextColor(Color.WHITE);
tv.setTextSize(0, dimen[1] / 40);
tv.setTypeface(Typeface.createFromAsset(context.getAssets(),"fonts/font.otf"));

2
不确定 API 是否有所更改,但 bar.getView 返回一个 View 对象,正如您所知道的,您无法向视图添加子项。 - Alberto M
3
是的,Api已经改变了,现在你只需要将它转换为SnackbarLayout。其他都是相同的。 - kasra Arab

3

2

Kotlin 2021:

fun showLoadingSnackbar(){
    val snackbar: Snackbar = Snackbar.make(findViewById(R.id.rootlayoutid), "TEXT or RES", Snackbar.LENGTH_INDEFINITE)
    val viewGroup = snackbar.view.findViewById<View>(com.google.android.material.R.id.snackbar_text).parent as ViewGroup
    viewGroup.addView(ProgressBar(this))// Or Context if not in Activity
    snackbar.show()
}

如果你想把它放在左边,只需调用addView(ProgressBar(this),0),如其他答案中所述。

编辑:如果文本太长,答案会将进度条放在顶部,因此要使其居中,可以执行以下操作:

val snackbar: Snackbar = Snackbar.make(this, text, duration)
    val viewGroup = snackbar.view.findViewById<View>(com.google.android.material.R.id.snackbar_text).parent as ViewGroup
    viewGroup.addView(ProgressBar(context).also {
        it.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
        it.foregroundGravity = Gravity.CENTER_VERTICAL
    })
snackbar.show()

1
我认为您可以设计一个自定义进度对话框,使其外观类似于Snackbar,因为Snackbar在加载时不会阻止用户与GUI的交互。
更新:
请尝试以下操作:
创建动画资源文件并将其命名为slide_in.xml,然后粘贴以下内容:
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYDelta="50%p" android:toYDelta="0%p"
android:duration="@android:integer/config_longAnimTime"
/>

创建另一个动画资源文件,命名为slide_out.xml:

<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_longAnimTime"
android:fromYDelta="0%p"
android:toYDelta="100%p" />

现在将进程对话框样式放置在样式资源中:
<style name="CustomDialog" parent="@android:style/Theme.Holo.Dialog">
    <item name="android:windowMinWidthMajor">100%</item>
    <item name="android:windowMinWidthMinor">100%</item>
    <item name="android:background">#323232</item>
    <item name="android:textColor">#FFFFFF</item>
    <item name="android:windowBackground">@color/transparent</item>
    <item name="android:backgroundDimEnabled">true</item>
    <item name="android:alertDialogStyle">@style/customDialogStyle</item>
    <item name="android:windowAnimationStyle">@style/DialogAnimation</item>

</style>

<style name="customDialogStyle">
    <item name="android:bottomBright">@android:color/transparent</item>
    <item name="android:bottomDark">@android:color/transparent</item>
    <item name="android:bottomMedium">@android:color/transparent</item>
    <item name="android:centerBright">@android:color/transparent</item>
    <item name="android:centerDark">@android:color/transparent</item>
    <item name="android:centerMedium">@android:color/transparent</item>
    <item name="android:fullBright">@android:color/transparent</item>
    <item name="android:fullDark">@android:color/transparent</item>
    <item name="android:topBright">@android:color/transparent</item>
    <item name="android:topDark">@android:color/transparent</item>

将此放置以进行动画:

<style name="DialogAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_in</item>
    <item name="android:windowExitAnimation">@anim/slide_out</item>
</style>

现在添加你的方法:

public static ProgressDialog processSnackbar(Context context,String s){
    ProgressDialog pSnackbar = new ProgressDialog(context, R.style.CustomDialog) {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            ProgressBar progress = (ProgressBar) findViewById(android.R.id.progress);
            LinearLayout bodyLayout = (LinearLayout) progress.getParent();
            TextView messageView = (TextView) bodyLayout.getChildAt(1);

            messageView.setPadding(20,0,0,0);
            LinearLayout.LayoutParams llp =
                    (LinearLayout.LayoutParams) messageView.getLayoutParams();
            llp.width = 0;
            llp.weight = 1;


            bodyLayout.removeAllViews();
            bodyLayout.addView(messageView, llp);
            bodyLayout.addView(progress);
        }
    };
    pSnackbar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    pSnackbar.setMessage(s);
    pSnackbar.getWindow().setGravity(Gravity.BOTTOM);
    pSnackbar.setCancelable(false);
    return pSnackbar;
}

方法 Credit 返回 @mike-m 的引用是否可能更改进度对话框的消息或旋转器位置?

我也在我的应用程序中使用这个,看一下:

snickersBar


你可以如何使用ACTION来完成这个任务? - TheRealChx101

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接