动作栏下的ProgressBar


79

问题摘要:我如何像在Chrome App上那样ProgressBar在内集成ActionBar

详细信息:查看Chrome的以下屏幕截图:

Chrome for Android屏幕截图

我想像这样创建一个动作栏。在操作栏的下面,有一个根据页面加载情况填充的ProgressBar。我已经从许多应用程序(例如Feedly)中看到了这个示例,但是我无法创建自己的实现。我尝试使用Android自己的API创建它:

@Override
protected void onCreate(Bundle savedInstanceState) {
    //Request Permission to display the Progress Bar...
    this.requestWindowFeature(Window.FEATURE_PROGRESS);
            this.setWindowContentView(R.layout.activity_main)
    super.onCreate(savedInstanceState);

    this.setProgressBarIndeterminate(true);
}

但是此代码只会使ProgressBar显示操作栏上,如下所示:

我的应用程序截图

因此,如何使ProgressBar出现在操作栏下方,就像在Chrome应用程序上一样?


这个答案可能重复的问题:stackoverflow.com/a/10755545/794088
petey

您找到解决方案了吗?
艾瑞克(Eric)

我奶奶的屏幕快照
IlyaEremin 2014年

Answers:


7

现在这是可以使用SwipeRefreshLayout获得的本机行为。

您可以使用来包装可滚动视图,SwipeRefreshLayout然后只需要监听onRefresh事件:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
    swipeLayout.setOnRefreshListener(this);
    swipeLayout.setColorScheme(android.R.color.holo_blue_bright, 
            android.R.color.holo_green_light, 
            android.R.color.holo_orange_light, 
            android.R.color.holo_red_light);
}


@Override public void onRefresh() {
    new Handler().postDelayed(new Runnable() {
        @Override public void run() {
            swipeLayout.setRefreshing(false);
        }
    }, 5000);
}

可以在此博客中找到一个很好而简单的教程。


56

我对上面接受的答案并不完全满意,所以我自己做了一些额外的研究。

我相信他们使用的技巧是,他们在称为 DecorView并在其中添加了进度条。这样,进度条将同时显示在操作条和内容区域上。请注意,SD的答案将进度条置于内容区域,并从实际内容中“窃取”空间,这可能导致意外结果。

此实现的示例屏幕截图

进度条

进度条不确定

只需将这段代码放入onCreate某些活动的方法中,它应该可以工作:

// create new ProgressBar and style it
final ProgressBar progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 24));
progressBar.setProgress(65);

// retrieve the top view of our application
final FrameLayout decorView = (FrameLayout) getWindow().getDecorView();
decorView.addView(progressBar);

// Here we try to position the ProgressBar to the correct position by looking
// at the position where content area starts. But during creating time, sizes 
// of the components are not set yet, so we have to wait until the components
// has been laid out
// Also note that doing progressBar.setY(136) will not work, because of different
// screen densities and different sizes of actionBar
ViewTreeObserver observer = progressBar.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        View contentView = decorView.findViewById(android.R.id.content);
        progressBar.setY(contentView.getY() - 10);

        ViewTreeObserver observer = progressBar.getViewTreeObserver();
        observer.removeOnGlobalLayoutListener(this);
    }
});

您可以使用LayoutParams的height参数来将progressBar设置为更宽或更窄,但是您可能必须调整-10偏移量。

造型

不幸的是,您可以看到进度条的难看的灰色背景。要删除它,仅通过id搜索背景并尝试隐藏它是行不通的。要删除背景,我必须创建与系统版本相同的对象,并删除背景项。

TL; DR:创建文件progress_horizontal_holo_no_background_light.xml并粘贴此可绘制对象:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@android:id/secondaryProgress">
        <scale android:scaleWidth="100%"
               android:drawable="@drawable/progress_secondary_holo_light" />
    </item>

    <item android:id="@android:id/progress">
        <scale android:scaleWidth="100%"
               android:drawable="@drawable/progress_primary_holo_light" />
    </item>

</layer-list>

将适当的.png可绘制对象从复制sdk/platforms/android-xx/data/res/drawable-xxx/到您的项目中,然后在代码中添加:

progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.progress_horizontal_holo_no_background_light));

附加:不确定进度条

不确定进度条的KitKat之前版本非常丑陋和缓慢。您可以下载名为的新的平滑progressBar ButteryProgressBar。只需在google上搜索它(我无法发布更多链接,因为我是这里的新手:[),将该类添加到您的项目中,您可以使用以下代码替换以前的ProgressBar并拥有清晰的不确定进度条:

final ButteryProgressBar progressBar = new ButteryProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 24));

您可能还需要简化以下代码:

final TypedArray ta = c.obtainStyledAttributes(attrs, R.styleable.ButteryProgressBar);
try {
    mBarColor = ta.getColor(R.styleable.ButteryProgressBar_barColor,
            c.getResources().getColor(android.R.color.holo_blue_light));
    mSolidBarHeight = ta.getDimensionPixelSize(
            R.styleable.ButteryProgressBar_barHeight,
            Math.round(DEFAULT_BAR_HEIGHT_DP * mDensity));
    mSolidBarDetentWidth = ta.getDimensionPixelSize(
            R.styleable.ButteryProgressBar_detentWidth,
            Math.round(DEFAULT_DETENT_WIDTH_DP * mDensity));
} finally {
    ta.recycle();
}

此代码:

mBarColor = c.getResources().getColor(android.R.color.holo_blue_light);
mSolidBarHeight = Math.round(DEFAULT_BAR_HEIGHT_DP * mDensity);
mSolidBarDetentWidth = Math.round(DEFAULT_DETENT_WIDTH_DP * mDensity);

希望我能帮到:)


不推荐使用类型为ViewTreeObserver的方法removeGlobalOnLayoutListener(ViewTreeObserver.OnGlobalLayoutListener)
Frozen Crayon Crayon

@ArjunU。我们应该用什么代替>
Patrick Geyer


我已经测试了不确定的进度栏(ButteryProgressBar),ActionBarActivity但是它不起作用。如何在下方放置不确定的进度条ActionBar/Toolbar?这是我正在使用的布局:stackoverflow.com/a/26440880/1480019
user1480019 2014年

2
@GerritHoekstra:万一getSupportActionBar().getHeight()函数起作用了,您就快到了。该progressBar.setY()功能设置相对于屏幕顶部的位置,包括状态栏。所以,您要做的就是setY(supportActionBarHeight + Math.ceil(25 * context.getResources().getDisplayMetrics().density))。状态栏的高度为25px(mdpi),缩放比例更高(hdpi / xhdpi / ...)。尝试一下并告诉我它是否有效。
Antimonit

25

从下一个类扩展Activity,以在每个类的顶部(在ActionBar之下)具有一个ProgressBar,以及一个getProgressBar()方法:

家长班:

public abstract class ProgressActivity extends Activity {
    private ProgressBar mProgressBar;

    @Override
    public void setContentView(View view) {
        init().addView(view);
    }

    @Override
    public void setContentView(int layoutResID) {
        getLayoutInflater().inflate(layoutResID,init(),true);
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        init().addView(view,params);
    }

    private ViewGroup init(){
        super.setContentView(R.layout.progress);
        mProgressBar = (ProgressBar) findViewById(R.id.activity_bar);
        return (ViewGroup) findViewById(R.id.activity_frame);
    }

    protected ProgressBar getProgressBar(){
        return mProgressBar;
    }
}

布局(progress.xml):

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"
    android:layout_width="match_parent" android:layout_height="match_parent">
<ProgressBar android:id="@+id/activity_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="-8dp"
    style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"
    />
  <FrameLayout android:id="@+id/activity_frame"
      android:layout_width="match_parent"
      android:layout_height="fill_parent"
      />
</LinearLayout>

1
它在大多数情况下都有效。ProgressBar看起来确实与操作栏分开。我必须将它添加android:layout_marginTop="-8dp"到ProgressBar才能模拟“阴影”效果。但是对于这种方法,将其添加到主布局本身可能更有效。但是现在它可以按预期工作了。感谢您的破解。
zubietaroberto

@zubietaroberto是的,如果仅将其用于一项活动,则可以将其添加到主布局。如果希望多个活动都具有此功能,则可以扩展上面显示的类。
SD

1
它为我工作,但是进度栏显示在选项卡主机下方,我如何才能使其在选项卡主机上方和动作栏下方?
DeckyFx


3

请使用下面的代码。只需在进度栏中使用一种默认样式即可style="?android:attr/progressBarStyleHorizontal"

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <ProgressBar 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleHorizontal"
        android:indeterminate="true"

        />

</RelativeLayout>

0

好吧,我为自己的一个宠物应用程序做了类似的事情,但不确定这是唯一的方法还是最好的方法,但是它确实有效。

首先,使用叠加操作栏,然后将背景可绘制背景设置为“ null”,以便叠加操作栏是透明的。

现在,在活动布局中,将根视图的上边距设置为“ actionbar height”。您可以这样做。

<RelativeLayout
    ...
    android:layout_marginTop="?android:attr/actionBarSize" />

现在,该动作将不会隐藏您的任何活动内容。

您现在要做的下一件事是-在根视图的顶部添加一个标题栏,其高度与操作栏相同。为其设置背景色。现在,这将是操作栏的颜色,并且由于该操作栏在此标题视图的顶部完美对齐。

现在,您可以轻松地在标题视图中放置一个进度条,并将其与标题视图的底部对齐。对于用户来说,这似乎是进度条位于动作条本身上,就像chrome ..

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.