Android SplashScreen


80

기본적으로 응용 프로그램 자체를 시작할 때 많은 데이터를 다운로드하여 ListActivity에 표시하는 응용 프로그램을 개발 중입니다. 내가 할 계획은 데이터가로드 될 때까지 스플래시 화면을 표시하는 것입니다.

지금까지 나의 모든 시도는 헛된 것이었다. anddev.org에서 언급 한 방법을 시도했지만 내 문제는 주요 활동이 시작되어야하지만 ListActivity를 채울 때까지 스플래시 화면이 표시되어야한다는 것입니다. 간단히 말해서 다음 단계를 거쳐야합니다.

  1. 내 주요 활동을 시작하십시오.
  2. 스플래시 화면을 표시합니다.
  3. 백그라운드에서 프로세스를 계속 실행하십시오.
  4. 처리가 완료되면 스플래시 화면을 종료하고 기본 목록을 표시합니다.

그것이 어떤 것인지 이해하기를 바랍니다 ....


아무도 내 메인 목록의 OnCreate 기능에서 생성하고 시작하려고해도 진행률 표시 줄이로드되지 않는다고 설명 할 수 있습니까? 그리고 내 프로세스가 완료된 후 닫습니다 ... 이것은 작동하지 않더라도 ... 내가 따라야 할 기본 방법이 있습니까? OnStart () 또는 뭔가에서 진행률 표시 줄을 시작하는 것과 같이 ??
JaVadid 2009

stackoverflow.com/questions/2222890/… 에서 허용되는 답변을 시도해 보셨습니까 ? 편집 : 좋아, 받아 들여진 대답은 좀 똑같다 ..
noloman

답변:


89

문제는 수행중인 모든 작업과 동일한 스레드에서 스플래시 화면 ( 내가 생각 하는 ProgressDialog 와 같은 일종의 대화 상자)을 실행하고있을 가능성이 큽니다 . 이렇게하면 스플래시 화면보기가 업데이트되지 않고 화면에 표시되지 않을 수도 있습니다. 시작 화면을 표시하고 AsyncTask 인스턴스를 시작하여 모든 데이터를 다운로드 한 다음 작업이 완료되면 시작 화면을 숨겨야합니다.

따라서 Activity의 onCreate () 메서드는 단순히 ProgressDialog를 만들고 표시합니다. 그런 다음 AsyncTask를 만들고 시작합니다. AsyncTask를 기본 Activity의 내부 클래스로 만들어서 Activity의 일부 변수에 다운로드 한 데이터를 저장하고 onPostExecute () 메서드에서 ProgressDialog를 닫을 수 있습니다.

코드를 보여주지 않고 더 이상 정교하게 만드는 방법을 모르기 때문에 여기에 있습니다.

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

분명히 거기에 채워야 할 몇 가지 부분이 있지만이 코드가 실행되고 좋은 시작점을 제공해야합니다 (코드 오류가있는 경우 용서해주세요. 입력 할 때 Android SDK에 액세스 할 수 없습니다. 현재).

Android의 AsyncTasks 주제에 대한 더 많은 좋은 자료는 여기여기 에서 찾을 수 있습니다 .


"데이터 개체로 교체"를 반환한다는 것은 무엇을 의미합니까? 나는 당신이 말한 것처럼 asynctask에로드하고 싶은 두 가지 기능이 있지만 무엇을 반환 해야할지 모르겠습니다. null을 반환하려고했지만 앱이 충돌합니다.
Nick

AsyncTask <String, Void, Object> 여기서 Object는 반환하려는 데이터 유형을 나타냅니다. 여기에서 "AsyncTask의 일반 유형"섹션을 참조하십시오. developer.android.com/reference/android/os/AsyncTask.html
Mark B

이것은 오래되었지만 알고 있지만 이것을 구현하려고 시도했으며 ProgressDialog(내 경우 레이아웃을로드하는 일반 대화 상자)는 표시되지 않습니다. .dismiss()에서 주석을다는 경우에만 볼 수 onPostExecute있습니다. 내가 보는 첫 번째 화면은 여전히 MyActivity테마입니다. 그 후 바로 R.layout.main.
Kevin_TA 2014 년

@Kevin_TA .dismiss ()로 인해 표시되지 않으면 AsyncTask가 즉시 종료됩니다. 내가 설명한 방법은 일부 장기 실행 시작 작업이 실행되는 동안 표시되는 시작 화면을 표시하는 것입니다.
Mark B

@mbaird 즉시 끝나지 않습니다. 실제로 완료하는 데 2-3 초가 걸리는 백그라운드 프로세스가 있습니다. 그러나 어떤 이유로 인해 비동기가 완료 될 때까지 UI의 아무 것도 업데이트되지 않아 목적이 무효화됩니다.
Kevin_TA 2014 년

61

참고로 이것이 스플래시 화면을 만드는 가장 좋은 방법입니다. http://android-developers.blogspot.de/2009/03/window-backgrounds-ui-speed.html

나는 이것을 안드로이드 문서에서 꽤 오랫동안 찾고 있었다. 검은 화면을 피하고 싶다면 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>

그리고이 테마를 주요 활동의 테마로 설정하십시오 ... TADA, 처음부터 시작 화면.

채우기 위해 늘어나는 이미지뿐만 아니라 복잡한 배경을 원할 경우 Drawables를 사용할 수 있습니다. 다음은 로고를 검은 색 배경으로 중앙에 유지하는 레이어 목록의 예입니다.

<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
이 링크는 죽은하지만 페이지의 콘텐츠와 소스 코드 archive.org로 볼 수 있습니다 : web.archive.org/web/20101113015720/http://developer.android.com/...
Spoonface

android : windowBackground에 드로어 블 대신 layout.xml을 사용하는 방법이 있습니까? 그렇게하려고하면 충돌이 발생하지만 해결 방법이 있는지 궁금합니다.
Kevin_TA 2014 년

@Kevin_TA 아니에요. 하지만 드로어 블을 사용할 수 있으므로 화면 중앙에 로고를 넣으려면 레이어 목록 드로어 블을 사용하고 중력을 사용하여 이미지를 배치해야합니다. 예를 들어 답변을 업데이트하겠습니다.
Raanan

1
@Ranaan 테마 솔루션이 저에게 효과적이지만 레이어 목록을 테마에 어떻게 연결해야합니까?
deko

2
@deko item name = "android : windowBackground"는 고정 된 색상 또는 이미지이거나 res / drawable 폴더에 배치 된 레이어 목록과 같은 xml 드로어 블일 수 있습니다. 여기 드로어 블 Drawable에 대해 읽을 수 있습니다 developer.android.com/guide/topics/resources/...
Raanan

1

스플래시 화면 예 :

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. 내 주요 활동을 시작하십시오.
  2. 스플래시 화면을 표시합니다.
  3. 백그라운드에서 프로세스를 계속 실행하십시오.
  4. 처리가 완료되면 스플래시 화면을 종료하고 기본 목록을 표시합니다.

이런 식으로 시도했지만 문제는 다음과 같습니다. 스플래시 화면 활동을 시작하기 전에 주요 활동이 표시됩니다.

나는 이렇게 만들었다.

  1. 스플래시 화면 시작
  2. 프로세스가 완료되면 "주 활동"을 시작합니다.
  3. 뒤로 버튼을 처리하는 것을 잊지 마십시오. 앱을 닫아야합니다. 메인 활동에서 눌려 질 것입니다. 그렇지 않으면 스플래시 화면으로 돌아갑니다 (루프).

내 문제는 메뉴 버튼을 눌러 "스플래시 화면 활동의 메뉴 표시"를 비활성화하는 방법입니다.

편집하다:

표시 메뉴 비활성화 :

@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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.