Загрузка изображений в ImageView в Android в отдельном потоке (Java)

Сегодня покажу как загружать изображения с сервера и помещать их в ImageView в Android в отдельном потоке.

Как загрузить изображение с сервера

Начать стоит с того, что изображение должно загружаться в отдельном потоке, а помещаться в контрол в главном потоке.

Чтобы реализовать данную задачу, необходимо создать класс, являющийся наследником класса AsyncTask.

В данном случае я создал класс ImageLoadAsync, наследующий AsyncTask<ImageView, Void, Bitmap>.

package razilov.pro.rus_butik;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class ImageLoadAsync extends AsyncTask<ImageView, Void, Bitmap> {
    String Url;
    ImageView imgV;

    /* onPostExecute и onPreExecute имеют доступ к UI. Можно взаимодействовать с элементами
     * формы (передав их перед этим в конструкторе) */

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);
        imgV.setImageBitmap(bitmap);
    }

    /* Все ссылки и прочий хлам можно передать в конструкторе */
    public ImageLoadAsync(String url, ImageView imgV){
        this.Url = url;
        this.imgV = imgV;
    }


    private Bitmap download_Image(String url) {
        try {
            URL urlstring = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) urlstring.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (MalformedURLException mex) {
            System.out.println(mex);
            return null;
        } catch (IOException ioex) {
            System.out.println(ioex);
            return null;
        }
    }

    @Override
    protected Bitmap doInBackground(ImageView... params) {
        return download_Image(this.Url);
    }
}

В этом коде в отдельном потоке подгружается Bitmap и передается в поток, имеющий доступ к интерфейсу, откуда не составляет труда присвоить этот Bitmap контролу ImageView.

 

Работа с анимацией в Android (Java, XML)

В данном посте рассматривается работа с анимацией в Android.

Для начала необходимо в папке Res создать папку anim и выбрать Resource type anim. Затем добавлять файлы Animation Resourse File в эту папку.

Далее рассмотрим примеры анимаций.

Анимация прозрачности

<?xml version="1.0" encoding="utf-8"?>
<alpha
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromAlpha="0.0"
  android:toAlpha="1.0"
  android:duration="3000">
</alpha>

Анимация перемещения

<?xml version="1.0" encoding="utf-8"?>
<translate
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromXDelta="-150"
  android:toXDelta="0"
  android:fromYDelta="-200"
  android:toYDelta="0"
  android:duration = "3000">
</translate>

Анимация поворота

<?xml version="1.0" encoding="utf-8"?>
<rotate
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromDegrees="0"
  android:toDegrees="360"
  android:duration = "3000">
</rotate>

Анимация масштабирования

<?xml version="1.0" encoding="utf-8"?>
<scale
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromXScale="0.1"
  android:toXScale="1.0"
  android:fromYScale="0.1"
  android:toYScale="1.0"
  android:pivotX="50%"
  android:pivotY="50%"
  android:duration="3000">

Использование сразу нескольких эффектов анимаций

Объединяем анимации разворота и масштабирования:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <rotate
    android:fromDegrees="0"
    android:toDegrees="360"
    android:duration="3000"
    android:pivotY="50%"
    android:pivotX="50%">
  </rotate>
  <scale
    android:fromXScale="0.1"
    android:toXScale="1.0"
    android:fromYScale="0.1"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="3000">
  </scale>
</set>

Запуск анимации через контекстное меню

В приведенном ниже коде описанные анимации запускаются через контекстное меню:

package razilov.ru;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

  private TextView textView;

  private final int MENU_ALPHA_ID = 1;
  private final int MENU_SCALE_ID = 2;
  private final int MENU_TRANSLATE_ID = 3;
  private final int MENU_ROTATE_ID = 4;
  private final int MENU_COMBO_ID = 5;

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    switch (v.getId()){
      case R.id.textView:
      menu.add(0, MENU_ALPHA_ID, 0, "Alpha");
      menu.add(0, MENU_SCALE_ID, 0, "Scale");
      menu.add(0, MENU_TRANSLATE_ID, 0, "Translate");
      menu.add(0, MENU_ROTATE_ID, 0, "Rotate");
      menu.add(0, MENU_COMBO_ID, 0, "Combo");
    }
    super.onCreateContextMenu(menu, v, menuInfo);
  }

//Работа с анимацией
  @Override
  public boolean onContextItemSelected(MenuItem item) {
    Animation anim = null;

    switch (item.getItemId()){
      case MENU_ALPHA_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.myalpha);
      break;
      case MENU_SCALE_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.myscale);
      break;
      case MENU_TRANSLATE_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.mytrans);
      break;
      case MENU_ROTATE_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.myrotate);
      break;
      case MENU_COMBO_ID:
      anim = AnimationUtils.loadAnimation(this, R.anim.mycombo);
      break;
    }

    textView.startAnimation(anim);
    return super.onContextItemSelected(item);
  }

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

    textView = (TextView)findViewById(R.id.textView);
    registerForContextMenu(textView);
  }
}

Код очень простой. Если есть вопросы, задавайте.

Результат приведенного кода привожу по ссылке.

Программное добавление элементов в Android (Java)

В этой статье разбираемся как осуществить программное добавление элементов в Android. В следующем фрагменте кода показано объявление элементов, настройка их параметров и отображение их в LinearLayout.

Добавляем элементы в активити из кода

Привожу пример программного добавления элементов:

package razilov.ru;

import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        ViewGroup.LayoutParams linLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        setContentView(linearLayout, linLayoutParams);


        ViewGroup.LayoutParams lpView = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        TextView tv = new TextView(this);
        tv.setText("TextView");
        tv.setLayoutParams(lpView);
        linearLayout.addView(tv);

        Button btn = new Button(this);
        btn.setText("Button");
        linearLayout.addView(btn, lpView);

        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.leftMargin = 50;

        Button btn1 = new Button(this);
        btn1.setText("Btn1");
        linearLayout.addView(btn1, layoutParams);

        LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams1.gravity = Gravity.RIGHT;

        Button btn2 = new Button(this);
        btn2.setText("btn2");
        linearLayout.addView(btn2, layoutParams1);

    }
}

Функция addView добавляет элемент в контрол.