Carregamento adequado de conteúdo de fundo no Android

Minha primeira dica profissional precisa ser baseada no Android, com certeza .

Você sabe … desenvolver aplicativos Android é uma tarefa legal, mas desenvolver aplicativos Android bonitos é uma tarefa muito mais legal.

Não é fácil conseguir isso, você precisa fazer algumas pesquisas no site oficial do Android Developer and Design , olhar para belos aplicativos e muito mais.

Mas vamos dar uma olhada nesta imagem:
Bom progresso

Imagem de + Roman Nurik no Google+

O primeiro com um velho diálogo parece desajeitado e feio e o segundo parece elegante, simples e bonito.

Bem, como posso fazer isso?

Peça fácil, só precisamos nos lembrar de 3 coisas:

  1. precisamos de um layout adequado
  2. precisamos de uma atividade adequada
  3. AsyncTask é uma corrida mestre

Nada mais, olhe para este pedaço de código para o layout:

activity_onload.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout >="http://schemas.android.com/apk/res/android"
>="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoadedActivity" >

<!-- another layout that will be wrapped inside our layout -->
<include layout="@layout/loaded_content" />

<ProgressBar android:id="@+id/loading_spinner"
style="?android:progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>

Você apenas define o ProgressBar envolvido em um FrameLayout e inclui um layout de conteúdo.

carregado_content.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView >="http://schemas.android.com/apk/res/android"
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<!-- in my example I will load an image from the network -->
<ImageView
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</ScrollView>

Novamente, outro layout fácil, usei um ImageView porque irei carregar uma imagem pela Internet, então você deve adicionar a permissão de Internet adequada para fazer isso.

(Usei uma imagem de Victoria Justice porque ela está incrível, não me julgue.)

LoadedActivity.java

public class LoadedActivity extends Activity {

private View mContentView;
private View mLoadingView;
private int mAnimationDuration;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView
(R.layout.activity_loaded);

// save the content
mContentView
= findViewById(R.id.content);

// save the loading spinner
mLoadingView
= findViewById(R.id.loading_spinner);

// remove content
mContentView
.setVisibility(View.GONE);

// save the animation duration
mAnimationDuration
= getResources().getInteger(android.R.integer.config_longAnimTime);

// save the imageView (at our content layout)
ImageView imgView = (ImageView) findViewById(R.id.imageview);

// the tag will hold the url to our image
imgView
.setTag("http://i.imgur.com/8or6G.jpg");

// download our image with an asynctask look at the "post" event to see the loading process
new DownloadImageTask(mContentView, mLoadingView, mAnimationDuration).execute(imgView);
}

como você pode ver, no método onCreate, acabei de definir a visibilidade da visualização do conteúdo como View.GONE e isso resolve o problema.

Olhe para o método postExecute DownloadImageTask e aí está a mágica, a classe DownloadImageTask fará o trabalho de carregamento e a animação.

DownloadImageTask.java

private class DownloadImageTask extends AsyncTask<ImageView, Void, Bitmap> {

// reference to our imageview
private ImageView mImage;
private View mContent;
private View mSpinner;
private int mDuration;

public DownloadImageTask(View content, View spinner, int duration) {
mContent
= content;
mSpinner
= spinner;
mDuration
= duration;
}

/**
* The system calls this to perform work in a worker thread and

* delivers it the parameters given to AsyncTask.execute()

*/

protected Bitmap doInBackground(ImageView... images) {
mImage
= images[0];
String url = (String)image.getTag();
return loadImageFromNetwork(url);
}

@Override
protected void onPostExecute(Bitmap result) {
// Set the image view before the content is shown.
mImage
.setImageBitmap(result);

// Set the "show" view to 0% opacity but visible, so that it is visible
mContent
.setAlpha(0f);
mContent
.setVisibility(View.VISIBLE);

// Animate the "show" view to 100% opacity, and clear any animation listener set on the view.
mContent
.animate()
.alpha(1f)
.setDuration(mShortAnimationDuration)
.setListener(null);

// Animate the "hide" view to 0% opacity.
mSpinner
.animate()
.alpha(0f)
.setDuration(mShortAnimationDuration)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
hideView
.setVisibility(View.GONE);
}
});
}

/**
* download an image from the internet!

* @param url

* @return

*/

private Bitmap loadImageFromNetwork(String url) {
Bitmap bm = null;
try {
URL urln
= new URL(url);
bm
= BitmapFactory.decodeStream(urln.openConnection().getInputStream());
} catch (IOException e) {
Log.e("HUE","Error downloading the image from server : " + e.getMessage().toString());
}
return bm;
}
}

E isso é tudo o que você precisa para carregar conteúdo em segundo plano de uma maneira muito simples, elegante e bonita.

Lembre-se: mantenha-o simples, estúpido .

PS. Algum dia, vou aprender a formatar o código em coderwall.com, enquanto isso, devo usar Gist público ou outra coisa.