79

質問の概要: Chromeアプリのように、ProgressBar内部に統合するにはどうすればよいですか?ActionBar

詳細: Chromeのこのスクリーンショットを見てください:

ChromeforAndroidのスクリーンショット

このようなアクションバーを作りたいです。アクションバーのすぐ下に、ページの読み込みに応じて塗りつぶされるプログレスバーがあります。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がアクションバーの上に表示されるだけです。

マイアプリのスクリーンショット

では、Chromeアプリのように、プログレスバーをアクションバーの下に表示するにはどうすればよいですか?

4

6 に答える 6

56

私は上記の受け入れられた答えに完全に満足していなかったので、私は自分でいくつかの追加の調査をしました。

彼らが使用したと私が信じるトリックは、呼び出されたビュー階層のトップビューを取得しDecorView、そこにプログレスバーを追加したことです。このように、プログレスバーはアクションバーとコンテンツ領域の両方に表示されます。SDの回答は、プログレスバーをコンテンツ領域に配置し、実際のコンテンツからスペースを「盗む」ことに注意してください。これにより、予期しない結果が生じる可能性があります。

この実装のサンプルスクリーンショット:

プログレスバー

ProgressBarIndeterminate

コード

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

追加:不確定なプログレスバー

不確定なプログレスバーのPre-KitKatバージョンは、かなり醜くて遅れています。と呼ばれる新しいスムーズなprogressBarをダウンロードできますButteryProgressBar。グーグルで検索するだけです(私はここで新しいので、これ以上リンクを投稿できません:[)、クラスをプロジェクトに追加すると、以前の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);

私が助けてくれたことを願っています:)

于 2014-06-08T03:13:32.263 に答える
25

次のクラスからアクティビティを拡張して、各クラスの上部(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>
于 2013-02-25T18:19:53.050 に答える
7

これは、 SwipeRefreshLayoutを使用して取得できるネイティブの動作になりました。

スクロール可能なビューをでラップすると、 onRefreshイベントSwipeRefreshLayoutをリッスンする必要があります。

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

このブログには、素晴らしくシンプルなチュートリアルがあります。

于 2015-02-20T17:30:35.320 に答える
4

このスレッドとStackOverflowの他のスレッドからコードをコンパイルし、ButteryProgessbarの実装と「プルダウンして更新」に使用できるプロジェクトを作成しました。https://github.com/pauldmps/Gmail-like-Pull-Down-to-Refresh

アプリケーションでコードを自由に使用してください。

皆さん、どうもありがとうございました。

于 2014-07-26T17:20:54.690 に答える
3

以下のコードを使用してください。進行中のバーのデフォルトのスタイルを1つだけ使用します。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>
于 2014-05-12T12:47:04.920 に答える
0

ええと、私は私のペットアプリの1つに対して同様のことをしました、そしてそれがそれをする唯一の方法であるか最良の方法であるかはわかりませんが、それは間違いなく機能します。

まず、オーバーレイアクションバーを使用してから、背景ドローアブルを「null」に設定して、オーバーレイアクションバーが透明になるようにします。

アクティビティレイアウトで、ルートビューの上部マージンを「アクションバーの高さ」に設定します。このように行うことができます。

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

これで、アクションによってアクティビティコンテンツが非表示になることはありません。

次に行う必要があるのは、アクションバーと同じ高さのヘッダービューをルートビューの上に追加することです。それに背景色を設定します。これがアクションバーの色になり、アクションバーがこのヘッダービューの上部に完全に配置されるためです。

これで、プログレスバーをヘッダービューに簡単に配置して、ヘッダービューの下部に揃えることができます。ユーザーには、これは、クロームのように、プログレスバーがアクションバー自体にあるように見えます。

于 2014-04-06T20:23:28.407 に答える