Android SplashScreen


79

Tôi đang phát triển một ứng dụng về cơ bản tải xuống rất nhiều dữ liệu khi bắt đầu ứng dụng và hiển thị nó trong ListActivity. Những gì tôi định làm là hiển thị một màn hình Splash cho đến khi dữ liệu được tải.

Cho đến bây giờ mọi nỗ lực của tôi đều vô ích. Tôi đã thử các phương thức được đề cập đến vàdev.org, nhưng vấn đề của tôi là hoạt động chính nên bắt đầu nhưng màn hình Splash sẽ hiển thị cho đến khi tôi điền vào ListActivity của mình. Vì vậy, trong ngắn hạn, tôi phải đi qua các bước sau:

  1. Bắt đầu hoạt động chính của tôi.
  2. Hiển thị màn hình Splash.
  3. Tiếp tục chạy quá trình ở chế độ nền.
  4. Thoát khỏi Splashscreen khi xử lý hoàn tất và hiển thị Danh sách chính.

Hy vọng bạn hiểu những gì nó giống như ....

  0

Ai có thể giải thích y thậm chí một thanh tiến trình không tải ngay cả khi tôi cố gắng để tạo và bắt đầu nó trong chức năng OnCreate của Danh sách chính của tôi ... và loại bỏ nó sau khi quá trình của tôi kết thúc ... thậm chí điều này không làm việc ... ý tôi là có một ny phương pháp mặc định tôi cần phải làm theo ... như bắt đầu thanh tiến trình trong OnStart() hoặc một cái gì đó ?? 30 dec. 092009-12-30 11:11:21

  0

Bạn đã thử câu trả lời được chấp nhận trong http://stackoverflow.com/questions/2222890/how-to-make-a-splash-screen-screen-visible-when-app-starts có nói gì không? EDIT: Ok, câu trả lời được chấp nhận là kinda giống nhau .. 03 aug. 112011-08-03 19:37:06

  0

Kiểm tra điều này ra http://www.gadgetsaint.com/android/create-video-splash-screen-android/ 21 jan. 172017-01-21 21:44:45

89

Vấn đề là nhiều khả năng mà bạn đang chạy màn hình splash (một số loại Dialog như ProgressDialog tôi giả sử) trong cùng một thread như tất cả công việc đang được thực hiện. Điều này sẽ giữ cho chế độ xem của màn hình splash không bị cập nhật, điều này có thể giữ cho màn hình không bị hiển thị ngay cả trên màn hình. Bạn cần hiển thị màn hình giật gân, khởi động một thể hiện của AsyncTask để tải xuống tất cả dữ liệu của bạn, sau đó ẩn màn hình giật gân khi tác vụ hoàn tất.

Vì vậy, phương thức onCreate() của Activity sẽ đơn giản tạo ProgressDialog và hiển thị nó. Sau đó tạo AsyncTask và khởi động nó. Tôi sẽ làm cho AsyncTask trở thành một lớp bên trong của Activity chính của bạn, vì vậy nó có thể lưu trữ dữ liệu mà nó đã tải về một số biến trong Activity của bạn và đóng ProgressDialog trong phương thức onPostExecute() của nó.

Không chắc làm thế nào để xây dựng nữa mà không chỉ hiển thị các mã, do đó ở đây là:

public class MyActivity extends Activity { 
    private ProgressDialog pd = null; 
    private Object data = null; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     // Show the ProgressDialog on this thread 
     this.pd = ProgressDialog.show(this, "Working..", "Downloading Data...", true, false); 

     // Start a new thread that will download all the data 
     new DownloadTask().execute("Any parameters my download task needs here"); 
    } 

    private class DownloadTask extends AsyncTask<String, Void, Object> { 
     protected Object doInBackground(String... args) { 
      Log.i("MyApp", "Background thread starting"); 

      // This is where you would do all the work of downloading your data 

      return "replace this with your data object"; 
     } 

     protected void onPostExecute(Object result) { 
      // Pass the result data back to the main activity 
      MyActivity.this.data = result; 

      if (MyActivity.this.pd != null) { 
       MyActivity.this.pd.dismiss(); 
      } 
     } 
    }  
} 

Rõ ràng có một số mảnh bạn cần phải điền vào đó, nhưng mã này nên chạy và cung cấp cho bạn một tốt điểm bắt đầu (tha thứ cho tôi nếu có lỗi mã, tôi không có quyền truy cập vào SDK Android khi tôi đang nhập hiện tại này).

Một số đọc tốt hơn về chủ đề của AsyncTask trong Android có thể được tìm thấy herehere.

  0

Bạn có ý nghĩa gì khi trả lại "thay thế bằng dữ liệu vật" ? Tôi có hai chức năng của tôi mà tôi muốn tải trong asynctask như bạn nói nhưng tôi không biết những gì tôi giả sử để trở về. Tôi đã cố gắng trả về null nhưng ứng dụng bị treo. 13 feb. 122012-02-13 23:26:37

  0

AsyncTask <String, Void, Object> nơi Object đại diện cho kiểu dữ liệu bạn muốn trả về. Xem phần "Loại chung của AsyncTask" tại đây: http://developer.android.com/reference/android/os/AsyncTask.html 14 feb. 122012-02-14 00:14:33

  0

Đây là cũ, tôi biết, nhưng tôi đã thử triển khai thực hiện điều này và 'ProgressDialog' (trong trường hợp của tôi một Hộp thoại thông thường tải bố cục) sẽ không bao giờ được hiển thị. Tôi chỉ nhìn thấy nó nếu tôi nhận xét '.dismiss()' trong 'onPostExecute'. Màn hình đầu tiên tôi thấy vẫn là chủ đề 'MyActivity'. Sau đó nó đi thẳng đến 'R.layout.main'. 21 jan. 142014-01-21 21:33:46

  0

@Kevin_TA nếu .dismiss() đang khiến nó không hiển thị, khi đó AsyncTask của bạn sẽ kết thúc ngay lập tức. Phương pháp tôi phác thảo là để hiển thị một màn hình giật gân hiển thị trong khi một số nhiệm vụ khởi động chạy dài chạy. 22 jan. 142014-01-22 16:39:38

  0

@mbaird nó không kết thúc ngay lập tức.Tôi thực sự có một quá trình nền mà phải mất 2-3 giây để hoàn thành. Tuy nhiên, vì lý do nào đó, không có gì trên giao diện người dùng được cập nhật cho đến sau khi Async được thực hiện, do đó đánh bại mục đích. 22 jan. 142014-01-22 19:15:29

  0

@Kevin_TA thực tế là lệnh .dismiss() đang đóng nó ngay lập tức và lệnh .dismiss() xảy ra trong onPostExecute() cho tôi biết bạn không chạy quá trình nền của bạn dưới dạng AsyncTask. Bạn cần đảm bảo phương thức doInBackground() không trả lại cho đến khi quá trình nền của bạn hoàn tất. 23 jan. 142014-01-23 16:39:07

  0

có cách nào để hiển thị hình ảnh toàn màn hình (từ bản vẽ) thay vì hộp ProgressDialog không? 19 jul. 142014-07-19 09:28:26


58

chỉ để tham khảo đây là cách tốt nhất mà tôi tìm thấy để thực hiện một màn hình splash: http://android-developers.blogspot.de/2009/03/window-backgrounds-ui-speed.html

Tôi đã tìm kiếm này cho khá trong một, từ android docs .. nếu bạn muốn tránh những màn hình màu đen, bạn cần phải tạo chủ đề với windowBackground như vậy:

<resources> 
    <style name="Theme.Shelves" parent="android:Theme"> 
     <item name="android:windowBackground">@drawable/background_shelf</item> 
     <item name="android:windowNoTitle">true</item> 
    </style> 
</resources> 

Và đặt chủ đề này làm chủ đề cho hoạt động chính của bạn ... TADA, splashscreen từ giây đầu tiên.

Nếu bạn muốn có một nền phức tạp và không chỉ là một hình ảnh sẽ được kéo dài để lấp đầy bạn có thể sử dụng Drawables, đây là một ví dụ về một lớp-list mà sẽ giữ cho logo làm trung tâm với một nền đen:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 

    <item android:drawable="@color/black"> 
    </item> 
    <item> 
     <bitmap 
      android:gravity="center" 
      android:src="@drawable/logo" 
      android:tileMode="disabled" > 
     </bitmap> 
    </item> 
</layer-list> 
+1

liên kết này đã chết, nhưng nội dung trang và mã nguồn có sẵn trên archive.org: http://web.archive.org/web/20101113015720/http://developer.android.com/resources/articles/window- bg-speed.html 27 oct. 122012-10-27 01:30:49

  0

@Spoonface Cảm ơn, tôi đã cập nhật liên kết. 13 nov. 122012-11-13 19:01:49

  0

Có cách nào để sử dụng tệp layout.xml thay vì vẽ được cho android: windowBackground không? Tôi gặp tai nạn khi cố gắng làm như vậy, nhưng tôi tự hỏi liệu có cách giải quyết hay không. 22 jan. 142014-01-22 19:12:44

  0

@Kevin_TA không có. NHƯNG bạn có thể sử dụng Drawables vì ​​vậy nếu bạn muốn có một Logo ở giữa màn hình thì bạn nên sử dụng một danh sách lớp drawable và sử dụng lực hấp dẫn để định vị hình ảnh của bạn. Tôi sẽ cập nhật câu trả lời với một ví dụ. 23 jan. 142014-01-23 14:44:08

  0

@Ranaan Theme giải pháp làm việc cho tôi, nhưng làm thế nào tôi nên kết nối lớp danh sách với chủ đề? 08 apr. 142014-04-08 08:13:35

+1

@deko item name = "android: windowBackground" có thể là màu cố định hoặc hình ảnh hoặc xml có thể vẽ như danh sách lớp được đặt trong thư mục res/drawable của bạn. Bạn có thể đọc về Bản vẽ tại đây: http://developer.android.com/guide/topics/resources/drawable-resource.html 08 apr. 142014-04-08 09:32:28

  0

@Ranaan Tôi đã dùng thử, nhưng ứng dụng của tôi gặp sự cố khi bắt đầu với ngoại lệ: Dòng tệp XML nhị phân # 18: <bitmap> yêu cầu thuộc tính src hợp lệ 08 apr. 142014-04-08 12:24:53

  0

Vâng, bạn đang cung cấp gì trong bitmap src? nó phải là một hình ảnh có sẵn. (Bạn nên mở một câu hỏi mới) 08 apr. 142014-04-08 12:47:20

  0

@ Ranaan Bạn nói đúng, tôi đã làm: http://stackoverflow.com/questions/22940232/android-splash-screen-how-to-make-it-centered 08 apr. 142014-04-08 14:34:57

  0

Đây là Câu trả lời chính xác ! lam tôt lăm! 31 mar. 152015-03-31 16:39:11

  0

Đây phải là câu trả lời được chấp nhận! Từ rất nhiều quan điểm, điều này là tối ưu hơn các giải pháp khác. 18 feb. 162016-02-18 11:13:02

  0

Vâng đó là màn hình giật gân thực sự. Cảm ơn một tấn 16 apr. 162016-04-16 17:34:45


1
  1. Bắt đầu hoạt động chính của tôi.
  2. Hiển thị màn hình Splash.
  3. Tiếp tục chạy quá trình ở chế độ nền.
  4. Thoát khỏi Splashscreen khi xử lý hoàn tất và hiển thị Danh sách chính.

Tôi đã thử cách này, nhưng vấn đề là; nó sẽ hiển thị hoạt động chính trước khi bắt đầu hoạt động màn hình giật gân.

tôi đã thực hiện nó theo cách này:

  1. Bắt đầu màn hình Splash
  2. Khi quá trình được hoàn thành, bắt đầu "hoạt động chính"
  3. Không quên để xử lý các nút quay lại, vì vậy nó nên đóng Ứng dụng ist sẽ được nhấn trong hoạt động chính. Nếu không, sẽ quay lại màn hình giật gân (vòng lặp)

Vấn đề của tôi là cách tắt "hiển thị Menu của hoạt động màn hình Splash" bằng cách nhấn nút menu.

Edit:

chương trình đơn Disable:

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // getMenuInflater().inflate(R.menu.activity_main, menu); 
    return false; 
} 

@Override 
public boolean onMenuItemSelected(int featureId, MenuItem item) {  
    // return super.onMenuItemSelected(featureId, item); 
    return false; 
} 

1

Splash màn hình ví dụ:

public class MainActivity extends Activity { 
    private ImageView splashImageView; 
    boolean splashloading = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     splashImageView = new ImageView(this); 
     splashImageView.setScaleType(ScaleType.FIT_XY); 
     splashImageView.setImageResource(R.drawable.ic_launcher); 
     setContentView(splashImageView); 
     splashloading = true; 
     Handler h = new Handler(); 
     h.postDelayed(new Runnable() { 
      public void run() { 
       splashloading = false; 
       setContentView(R.layout.activity_main); 
      } 

     }, 3000); 

    } 

}