Android SplashScreen


80

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 dự định làm là hiển thị Splash Screen cho đến khi dữ liệu được tải.

Cho đến bây giờ mọi cố gắng của tôi đều vô ích. Tôi đã thử các phương pháp được đề cập trên anddev.org, nhưng vấn đề của tôi là Hoạt động chính sẽ bắt đầu nhưng Màn hình Splash sẽ hiển thị cho đến khi tôi điền ListActivity của mình. Vì vậy, tóm lại tôi phải trả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 Giật gân.
  3. Tiếp tục chạy quy trình trong nền.
  4. Thoát khỏi Splashscreen khi quá trình xử lý hoàn tất và hiển thị Danh sách chính.

Hy vọng bạn hiểu nó là như thế nào ....


Ai đó có thể giải thích cho bạn ngay cả khi thanh tiến trình không tải ngay cả khi tôi cố gắng tạo và khởi động 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 ... ngay cả khi điều này không hoạt động ... tôi có nghĩa là có bất kỳ phương pháp mặc định nào tôi cần làm theo ... như bắt đầu thanh tiến trình trong OnStart () hay gì đó không ??
JaVadid

Bạn đã thử câu trả lời được chấp nhận trong stackoverflow.com/questions/2222890/… nói gì chưa? CHỈNH SỬA: Được rồi, câu trả lời được chấp nhận cũng giống như vậy ..
noloman

Câu trả lời:


89

Vấn đề rất có thể là bạn đang chạy màn hình giật gân (một số loại Hộp thoại chẳng hạn như ProgressDialog mà tôi giả định) trong cùng một chủ đề với 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 giật gân không được cập nhật, điều này có thể khiến nó không được hiển thị 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 phiên bả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 nhiệm vụ hoàn tất.

Vì vậy, phương thức onCreate () trong Activity của bạn chỉ cần tạo một ProgressDialog và hiển thị nó. Sau đó, tạo AsyncTask và khởi động nó. Tôi sẽ đặt AsyncTask trở thành lớp bên trong của Activity chính của bạn, để nó có thể lưu trữ dữ liệu mà nó đã tải xuống vào 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 chắn làm thế nào để xây dựng thêm nữa mà không chỉ hiển thị mã, vì vậy đâ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 là có một số phần bạn cần điền vào đó, nhưng mã này sẽ chạy và cung cấp cho bạn điểm khởi đầu tốt (tha thứ cho tôi nếu có lỗi mã, tôi không có quyền truy cập vào Android SDK khi tôi đang nhập mã này hiện tại).

Bạn có thể tìm thấy một số bài đọc hay hơn về chủ đề AsyncTasks trong Android tại đâytại đây .


Ý bạn là gì khi trả về "thay thế bằng đối tượng dữ liệu"? Tôi có hai chức năng mà tôi muốn tải trong asynctask như bạn đã nói nhưng tôi không biết phải trả lại những gì. Tôi đã cố gắng trả về null nhưng ứng dụng bị lỗi.
Nick

AsyncTask <String, Void, Object> trong đó Object đại diện cho kiểu dữ liệu bạn muốn trả về. Xem phần "Các loại chung của AsyncTask" tại đây: developer.android.com/reference/android/os/AsyncTask.html
Mark B

Điều này là cũ, tôi biết, nhưng tôi đã thử triển khai điều này và ProgressDialog(trong trường hợp của tôi là Hộp thoại thông thường tải một bố cục) không bao giờ được hiển thị. Tôi chỉ nhìn thấy nó nếu tôi bình luận .dismiss()trong onPostExecute. Màn hình đầu tiên tôi thấy vẫn là MyActivitychủ đề. Sau đó nó đi thẳng đến R.layout.main.
Kevin_TA

@Kevin_TA nếu .dismiss () khiến nó không hiển thị, thì 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ố tác vụ khởi động đang chạy trong thời gian dài.
Mark B

@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ất 2-3 giây để hoàn thành. Tuy nhiên, vì một số lý do, không có gì trên giao diện người dùng được cập nhật cho đến khi Async được thực hiện, do đó không đạt được mục đích.
Kevin_TA

61

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

Tôi đã tìm kiếm điều này khá lâu, từ tài liệu android .. nếu bạn muốn tránh những màn hình đen đó, bạn cần tạo một chủ đề với windowBackground để:

<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, màn hình hiển thị ngay 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à ví dụ về danh sách lớp sẽ giữ logo ở giữa với 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: web.archive.org/web/20101113015720/http://developer.android.com/...
Spoonface

Có cách nào để sử dụng layout.xml thay vì drawable cho android: windowBackground không? Tôi gặp sự cố 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 nào không.
Kevin_TA

@Kevin_TA không, không có. NHƯNG bạn có thể sử dụng Drawable, vì vậy nếu bạn muốn có Logo ở giữa màn hình thì bạn nên sử dụng layer-list drawable và sử dụng trọng lực để đị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ụ.
Raanan

1
Giải pháp @Ranaan Theme phù hợp với tôi, nhưng tôi nên kết nối layer-list với chủ đề như thế nào?
deko

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

1

Ví dụ về màn hình giật gân:

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

    }

}

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

Tôi đã thử theo 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 trên màn hình giật gân.

Tôi đã làm theo cách này:

  1. Khởi động màn hình Splash
  2. Khi quá trình hoàn tất, hãy bắt đầu "hoạt động chính"
  3. Đừng quên xử lý nút quay lại, vì vậy nó sẽ đóng lại Ứng dụng 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à làm thế nào để vô hiệu hóa "hiển thị Menu của hoạt động trên màn hình Splash" bằng cách nhấn vào nút menu.

Biên tập:

Tắt menu hiển thị:

@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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.