2010-02-17 27 views
9

Tôi gặp sự cố khi đặt Bản vẽ mới cho ProgressBar của mình.Làm thế nào để sử dụng setProgressDrawable() một cách chính xác?

Nếu tôi sử dụng phương thức setProgressDrawable() bên trong phương thức onCreate(), nó hoạt động rất tốt. Nhưng khi tôi cố gắng gọi cùng một phương thức bên trong một handler post handler thì nó không hoạt động và thanh tiến trình biến mất.

Ai đó có thể giải thích hành vi này? Làm thế nào tôi có thể giải quyết vấn đề này?

+0

Thông thường, bạn sửa đổi tiến trình thông qua 'setProgress()'. Thay thế hoàn toàn 'Drawable' là không bình thường, thậm chí còn kỳ quặc hơn để thực hiện nó từ một' Handler' sau khi thanh đã được trả về. Bạn đang cố gắng đạt được điều gì ở đây? – CommonsWare

+0

Tôi muốn thay đổi màu sắc của thanh công cụ khi giá trị đã đạt đến một giá trị nhất định. – Martin

+1

Bạn đã bao giờ tìm thấy câu trả lời chưa? Tôi hiện có cùng một vấn đề (hơn một năm sau). Đây có phải chỉ là một lỗi lớn khó chịu? – Peanut

Trả lời

1

Bumped vào vấn đề này bản thân mình và tôi cố gắng làm cho nó làm việc :)

tôi đã sử dụng AsyncTask để xử lý nền nhiệm vụ/chủ đề, nhưng ý tưởng nên giống như sử dụng Runnable/Handler (mặc dù AsyncTask không cảm thấy đẹp hơn).

Vì vậy, đây là những gì tôi đã làm ... đặt setContentView(R.layout.my_screen); theo phương pháp onPostExecute! (. Tức là thay vì phương pháp onCreate)

Vì vậy, mã trông giống như sau:

public class MyScreen extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // setContentView(R.layout.my_screen); !!! Don't setContentView here... (see bottom) 

    new MySpecialTask().execute(); 
} 

private int somethingThatTakesALongTime() { 
    int result; 
    // blah blah blah 
    return result; 
} 

private void updateTheUiWithResult(int result) { 
    // Some code that changes the UI 
    // For exampe: 
    TextView myTextView = (TextView) findViewById(R.id.result_text); 
    myTextView.setText("Result is: " + result); 

    ProgressBar anyProgressBar = (ProgressBar) findViewById(R.id.custom_progressbar); 
    anyProgressBar.setProgressDrawable(res.getDrawable(R.drawable.progressbar_style)); 
    anyProgressBar.setMax(100); 
    anyProgressBar.setProgress(result);  
} 

private class MySpecialTask extends AsyncTask<String, Void, Integer> { 
    ProgressDialog mProgressDialog; 

    @Override 
    protected void onPreExecute() { 
     mProgressDialog = ProgressDialog.show(MyScreen.this, "", "Calculating...\nPlease wait...", true); 
    } 
    @Override 
    protected Integer doInBackground(String... strings) { 
     return somethingThatTakesALongTime(); 
    } 

    @Override 
    protected void onPostExecute(Integer result) { 
     mProgressDialog.dismiss(); 
     setContentView(R.layout.my_screen); // setContent view here... then it works... 
     updateTheUiWithResult(result); 
    } 
} 
} 

Thành thật mà nói, tại sao bạn cần phải gọi setContentView trong onPostExecute Tôi không có ý tưởng ... nhưng làm như vậy có nghĩa là bạn có thể đặt kiểu tùy biến cho các quán bar tiến bộ của bạn (và họ không biến mất vào bạn!)

+2

Đó là vì 'onPostExecute' được chạy trong cùng một luồng với giao diện người dùng, trong khi' doInBackground' được chạy trong một chuỗi nền, mà không thể vẽ trực tiếp đến giao diện người dùng http://developer.android.com/reference/android/os/AsyncTask.html – MartinodF

0

Có thể bạn đặt mã trong chuỗi không phải là chuỗi chính. Nếu bạn muốn làm việc với giao diện người dùng, bạn phải làm điều đó trong các chủ đề chính :)

+0

Nó nằm trong một chủ đề. Nhưng tôi sử dụng Handler.post (Runnable mới() để thao tác sẽ được xử lý bởi chuỗi giao diện người dùng. Nó hoạt động rất tốt để cập nhật giá trị thanh tiến trình (nhưng không thay đổi drawable) – Martin

+0

Chỉ cần trải nghiệm của tôi, nếu một số hoạt động như Các hộp thoại (có thể là ProgressBar giống nhau) được hiển thị một lần, bạn không thể thay đổi chúng nữa Giống như: bạn tạo một AlertDialog trong phương thức onCreateDialog không chứa một thông báo. Sau đó, trong phương thức onPrepareDialog, bạn thiết lập thông điệp - Sth như bộ nhớ đệm, như tôi nhớ –

12
downloadingBar.setProgress(0); 

Drawable progressDrawable = getResources().getDrawable(R.drawable.download_progressbar_pause_bg); 

progressDrawable.setBounds(downloadingBar.getProgressDrawable().getBounds()); 

downloadingBar.setProgressDrawable(progressDrawable); 

downloadingBar.setProgress(mCurrentPercent); 
  1. Trước tiên, bạn nên thiết lập lại tiến độ zero
  2. Đặt giới hạn tiến độ drawable
  3. Đặt bước tiến mới drawable
  4. Đặt bước tiến mới
+0

Có vẻ như nó hoạt động! (Tôi bỏ qua các giới hạn, bởi vì phương thức này không tồn tại trong 'ProgressBar').Đây có phải là tài liệu hack ở bất cứ đâu không? –

+0

getDrawable() không được chấp nhận ngay bây giờ API cập nhật >> Tiến trình có thể vẽDrawable = ContextCompat.getDrawable (context, R.drawable. Download_progressbar_pause_bg); – wadali

+0

cảm ơn, đã mất một khoảng thời gian trên http://i0.kym-cdn.com/entries/icons/original/000/000/554/facepalm.jpg – ThinkDeep

0

Tôi cũng đã phải đối mặt với cùng một vấn đề nhưng trong trường hợp của tôi đó là do việc sử dụng các Drawable.mutate() phương pháp . Khi tôi gỡ bỏ phương pháp đó, nó bắt đầu hoạt động tốt. Tôi cũng nhận thấy rằng vấn đề này tồn tại dưới api level-21 (lollipop).

Các vấn đề liên quan