Câu hỏi ProgressBar trong Action Bar


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:

Chrome for Android screenshot

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:

My App Screenshot

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?


76
2017-12-18 13:24


gốc


câu hỏi trùng lặp có thể có của câu trả lời này: stackoverflow.com/a/10755545/794088 - petey
bạn đã tìm ra giải pháp chưa? - Eric
ảnh chụp màn hình cho bà của tôi - IlyaEremin


Các câu trả lời:


Đâ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.


6
2018-02-20 17:30





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:

ProgressBar

ProgressBarIndeterminate

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


54
2018-06-08 03:13



Phương thức removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener) từ loại ViewTreeObserver không được chấp nhận - Arjun U.
@ArjunU. những gì chúng ta nên sử dụng thay vì> - Patrick Geyer
@PatrickGeyer thấy stackoverflow.com/questions/16189525/… - Arjun U.
Tôi đã thử nghiệm thanh tiến trình không xác định (ButteryProgressBar) với ActionBarActivity nhưng nó không hoạt động. Làm thế nào tôi có thể đặt một thanh tiến trình không xác định dưới ActionBar/Toolbar? Đây là cách bố trí những gì tôi đang sử dụng: stackoverflow.com/a/26440880/1480019 - user1480019
@GerritHoekstra: Trong trường hợp getSupportActionBar().getHeight() chức năng hoạt động, bạn gần như ở đó. Các progressBar.setY() chức năng đặt vị trí tương đối so với đầu màn hình, bao gồm cả thanh trạng thái. Vì vậy, những gì bạn phải làm là để setY(supportActionBarHeight + Math.ceil(25 * context.getResources().getDisplayMetrics().density)). Thanh trạng thái cao 25px (mdpi) và tỷ lệ với các giá trị cao hơn (hdpi / xhdpi / ...) Hãy thử và cho tôi biết nếu nó hoạt động. - Antimonit


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>

25
2018-02-25 18:19



Nó hoạt động ... cho hầu hết các phần. ProgressBar trông khác với thanh hành động. Tôi phải thêm android:layout_marginTop="-8dp" vào ProgressBar để mô phỏng hiệu ứng "bóng tối". Nhưng đối với phương pháp này, nó có lẽ là hiệu quả hơn để thêm nó vào chính bố trí chính nó. Tuy nhiên, bây giờ nó hoạt động như dự định. Cảm ơn bạn đã hack. - zubietaroberto
@zubietaroberto Có, Bạn có thể thêm nó vào bố cục chính nếu bạn chỉ sử dụng nó cho một hoạt động. Nếu bạn muốn nhiều hoạt động có tính năng này, bạn chỉ có thể mở rộng lớp được hiển thị ở trên. - S.D.
Công việc của nó cho tôi, nhưng thanh tiến trình xuất hiện dưới máy chủ tab, làm thế nào để tôi có thể làm cho nó ở trên tabhost và dưới thanh hành động? - DeckyFx


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.


4
2017-07-26 17:20





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>

2
2018-05-12 12:47





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 ..


0
2018-04-06 20:23