Tóm tắt câu hỏi: Làm thế nào tôi có thể làm một ProgressBar
tích hợp bên trong ActionBar
, như trên ứng dụng Chrome?
Chi tiết: Xem ảnh chụp màn hình này từ Chrome:

Tôi muốn tạo một Action Bar như thế này. Ngay bên dưới Action Bar, có một ProgressBar lấp đầy theo tải trang. Tôi đã thấy ví dụ này từ nhiều ứng dụng, như Feedly, nhưng tôi đã không thể tạo triển khai của riêng mình. Tôi đã thử sử dụng các API của riêng Android để tạo ra nó:
@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);
}
Nhưng mã này chỉ khiến ProgressBar hiển thị kết thúc Action Bar, như vậy:

Vì vậy, làm thế nào tôi có thể làm cho ProgressBar của tôi xuất hiện dưới thanh hành động, như trên ứng dụng Chrome?
Đây là một hành vi bản địa có thể thu được bằng cách sử dụng SwipeRefreshLayout.
Bạn có thể cuộn chế độ xem có thể cuộn bằng một SwipeRefreshLayout
và sau đó bạn chỉ cần lắng nghe onRefresh sự kiện:
@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);
}
Một hướng dẫn tốt và đơn giản có thể được tìm thấy trong blog này.
Tôi đã không hoàn toàn hài lòng với câu trả lời được chấp nhận ở trên, vì vậy tôi đã làm một số nghiên cứu thêm bản thân mình.
Bí quyết tôi tin rằng họ sử dụng là họ đã truy xuất chế độ xem hàng đầu trong cấu trúc phân cấp chế độ xem được gọi là DecorView
và thêm thanh tiến trình vào đó. Bằng cách đó, thanh tiến trình hiển thị cả trên thanh hành động VÀ vùng nội dung. Lưu ý rằng câu trả lời của S.D. đặt thanh tiến trình vào vùng nội dung và 'đánh cắp' không gian từ nội dung thực tế, điều gì có thể dẫn đến kết quả không mong muốn.
Mẫu vật ảnh chụp màn hình của việc triển khai này:


Mã số
Chỉ cần đặt mã này vào onCreate
phương pháp của một số hoạt động và nó sẽ hoạt động:
// 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);
}
});
Bạn có thể chơi với đối số chiều cao LayoutParams để đặt progressBar rộng hơn hoặc hẹp hơn, nhưng bạn có thể phải điều chỉnh -10
bù lại.
Tạo kiểu
Thật không may, bạn có thể thấy nền xám xấu xí của thanh tiến trình. Để loại bỏ nó, chỉ cần tìm kiếm nền theo id và cố gắng ẩn nó không hoạt động. Để loại bỏ nền, tôi đã phải tạo ra drawble giống hệt nhau của phiên bản hệ thống và loại bỏ các mục nền.
TL; DR: Tạo tệp progress_horizontal_holo_no_background_light.xml
và dán điều này:
<?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>
Sao chép các mục có thể rút .png thích hợp từ sdk/platforms/android-xx/data/res/drawable-xxx/
cho dự án của bạn và sau đó trong mã bạn có thể thêm:
progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.progress_horizontal_holo_no_background_light));
Thêm: Thanh tiến trình không xác định
Các phiên bản Pre-KitKat của các thanh tiến trình không xác định là khá xấu và lag.
Bạn có thể tải về tiến trình trơn tru mớiBar gọi là ButteryProgressBar
. Chỉ cần tìm kiếm nó trên google (tôi không thể đăng thêm liên kết nào nữa, vì tôi mới ở đây: [), thêm lớp vào dự án của bạn và bạn có thể thay thế ProgressBar trước đó bằng mã này và có thanh tiến trình không xác định giòn:
final ButteryProgressBar progressBar = new ButteryProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 24));
Bạn cũng có thể cần phải đơn giản hóa mã này:
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();
}
vào mã này:
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);
Hy vọng tôi đã giúp :)
Mở rộng các hoạt động từ lớp sau để có ProgressBar ở trên cùng (bên dưới ActionBar) của mỗi lớp và một getProgressBar()
phương pháp:
Lớp cha mẹ:
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;
}
}
Bố cục (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>
Tôi đã biên dịch mã từ chủ đề này cũng như các chủ đề khác trên StackOverflow và tạo ra một dự án có thể được sử dụng để thực hiện ButteryProgessbar cũng như "kéo xuống để làm mới". https://github.com/pauldmps/Gmail-like-Pull-Down-to-Refresh
Vui lòng sử dụng mã trong ứng dụng của bạn.
Xin cảm ơn các bạn.
Vui lòng sử dụng mã dưới đây. chỉ cần sử dụng một kiểu thanh mặc định trong thanh tiến trình 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>
Vâng, tôi đã làm một cái gì đó tương tự cho một trong những ứng dụng thú cưng của tôi và không chắc chắn nếu đó là cách duy nhất hoặc cách tốt nhất để làm điều đó, nhưng nó chắc chắn hoạt động.
Để bắt đầu, hãy sử dụng thanh tác vụ lớp phủ và sau đó đặt nền có thể vẽ thành "rỗng" để thanh tác vụ lớp phủ trong suốt.
Bây giờ trong bố trí hoạt động của bạn, đặt lề trên cho chế độ xem gốc của bạn thành "chiều cao thanh tác vụ" Bạn có thể làm điều đó như thế này.
<RelativeLayout
...
android:layout_marginTop="?android:attr/actionBarSize" />
Bây giờ hành động sẽ không ẩn bất kỳ nội dung hoạt động nào của bạn.
Điều tiếp theo bạn phải làm bây giờ là - thêm một khung nhìn tiêu đề ở trên cùng của khung nhìn gốc của bạn với chiều cao giống như thanh hành động. Đặt màu nền cho nó. Điều này bây giờ sẽ là màu sắc của thanh hành động của bạn và kể từ khi thanh hành động sắp xếp hoàn hảo trên đầu trang pf xem tiêu đề này.
Bây giờ bạn có thể dễ dàng đặt một thanh tiến trình trong khung nhìn tiêu đề và căn chỉnh nó ở dưới cùng của khung nhìn tiêu đề. Đối với người dùng, điều này có vẻ như thanh tiến trình nằm trên thanh tác vụ, giống như chrome ..