質問の概要: Chromeアプリのように、ProgressBar
をActionBar
内に統合するにはどうすればよいですか?
詳細: Chromeのスクリーンショットをご覧ください:
このようなアクションバーを作成したいと思います。アクションバーのすぐ下に、ページの読み込みに応じて表示される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にoverアクションバーのみが表示されます。
Chromeアプリのように、ProgressBarをアクションバーの下に表示するにはどうすればよいですか?
これは、 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);
}
素敵でシンプルなチュートリアルは、 このブログ にあります。
上記の受け入れられた答えに私は完全に満足していなかったので、自分でいくつかの追加調査を行いました。
彼らが使用したと思うトリックは、DecorView
と呼ばれるビュー階層のトップビューを取得し、そこにプログレスバーを追加したことです。これにより、進行状況バーはアクションバーとコンテンツ領域の両方に表示されます。 S.D.の答えは、プログレスバーをコンテンツエリアに配置し、実際のコンテンツからスペースを「盗む」ことに注意してください。これが予期しない結果につながる可能性があります。
サンプルscreenshotsこの実装の:
このコードを何らかのアクティビティの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
オフセットを調整する必要がある場合があります。
残念ながら、進行状況バーのofい灰色の背景を見ることができます。これを削除するには、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以前のバージョンは、かなりugくて遅れています。 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);
私が助けたことを願っています:)
アクティビティを次のクラスから拡張して、それぞれの最上部(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>
StackOverflowの他のスレッドと同様に、このスレッドからコードをコンパイルし、ButteryProgessbarを実装するために使用できるプロジェクトを作成し、「リフレッシュしてプルダウン」しました。 https://github.com/pauldmps/Gmail-like-Pull-Down-to-Refresh
アプリケーションでコードを自由に使用してください。
皆さんに感謝します。
以下のコードを使用してください。 style="?android:attr/progressBarStyleHorizontal"
として進行状況バーで1つのデフォルトスタイルを使用するだけです
<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>
まあ、私は私のペットアプリの1つに似たようなことをしましたが、それがそれを行う唯一の方法または最善の方法であるかどうかはわかりませんが、それは間違いなく動作します。
で開始するには、オーバーレイアクションバーを使用し、オーバーレイアクションバーが透明になるように、背景のドロアブルを「null」に設定します。
アクティビティレイアウトで、ルートビューの上余白を「アクションバーの高さ」に設定します。このようにできます。
<RelativeLayout
...
Android:layout_marginTop="?android:attr/actionBarSize" />
これで、アクションはアクティビティコンテンツを非表示にしません。
次に行う必要があるのは、アクションビューと同じ高さのルートビューの上にヘッダービューを追加することです。背景色を設定します。これは、アクションバーの色になります。アクションバーは、このヘッダービューの上部に完全に整列するためです。
これで、ヘッダービューにプログレスバーを簡単に配置し、ヘッダービューの下部に揃えることができます。ユーザーには、これはchrome ..のように、進行状況バーがアクションバー自体にあるように見えます。