in , ,

Android LiveData

LiveData , gözlemci modeliyle yaşam döngüsü duyarlı veri tutucu olarak sunulur . Bu, veri setinde yeni bir şey olduğunda haber vereceği anlamına gelir. Veri kümesindeki değişikliklerin görünümünü otomatik olarak değiştirir. Bu derste, LiveData android örneğini göstereceğiz.

LiveData , gözlemci modeliyle yaşam döngüsü duyarlı veri tutucu olarak sunulur . Bu, veri setinde yeni bir şey olduğunda haber vereceği anlamına gelir. Veri kümesindeki değişikliklerin görünümünü otomatik olarak değiştirir. Bu derste, LiveData android örneğini göstereceğiz.

LiveData nesnesine sahip olduğumuzda (örneğin, müşterilerin listesi, kullanıcıların bir listesi olabilir, herhangi bir veri kaynağı olabilir), bu veri güncellemesine gözlemci olarak bazı Yaşam Döngüsü Sahibini (Etkinlik veya Parça gibi) ekleriz. Gözlemci modeliyle aynı, ancak yaşam döngüsü durumlarına saygı göstererek.

Büyük uygulamada iki tür veri kaynağı olabilir. Yerel Sqlite veritabanı, uzak Dinlenme API’leri. Live ile, veri değişikliklerini gözlemlemek için bu veri kaynağını kodlayabilir ve görünümleri buna göre güncelleyebiliriz.

LiveData kullanmanın yararları

  • Kullanıcı arabiriminizin veri durumunuzla eşleşmesini sağlar – Bu, gözlemci modeline dayanır. Böylece, her seferinde ViewModel’den veri istemek yerine, veriler her değiştiğinde bilgilendirilecektir.
  • Bellek sızıntılarından kaçının – Yaşam döngüsü ile sınırlı ve yaşam döngüsü tahrip olduğunda gözlemciler LiveData nesnesi de yok eder.
  • Durdurulan faaliyetlerden dolayı çökme yok- Gözlemcinin yaşam döngüsü, örneğin arka yığında bir etkinlik olması durumunda etkin değilse, herhangi bir LiveData olayı almaz.
  • Artık manuel yaşam döngüsü kullanımı yok – UI bileşenleri yalnızca ilgili verileri gözlemler ve gözlemi durdurmaz veya sürdürmez. LiveData, gözlem yaparken ilgili yaşam döngüsü durumu değişikliklerinin farkında olduğu için tüm bunları otomatik olarak yönetir.
  • Her zaman güncel veriler – Bir yaşam döngüsü etkin olmazsa, tekrar etkinleştiğinde en son verileri alır. Örneğin, arka planda olan bir etkinlik, ön plana döndükten hemen sonra en son verileri alır.
  • Tüm konfigürasyon değişikliklerini yönetin – Bir cihazda yapılan değişiklik gibi bir konfigürasyon değişikliği nedeniyle bir aktivite veya fragman yeniden yaratılırsa, mevcut en son verileri derhal alır.

Uygulama LiveData için adım

  • Bizim app / build bağımlılıkları ekleyin . gradle dosya
  • AndroidViewModel veya ViewModel’in bir alt sınıfını oluşturun (örneğin)
  • Değişebilir canlı veri nesnesinden birini bildirin. Bu depodan veya diğer kaynaklardan girdi alır.
  • Aktivite’de bir LiveData örneği oluşturun ve gözlemciye abone olun.

1. EmptyActivity Template ile yeni bir proje oluşturun

AndroidStudio uygulamasında, LiveDataExample adında EmptyActivity şablonu olan yeni bir proje oluşturun. Şimdi sadece app / build.gradle bağımlılığını ekleyin.

def lifecycle_version = "1.1.1"
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"

    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    // Glide for image loading
    implementation 'com.github.bumptech.glide:glide:4.8.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'

Ayrıca bu projede lambda ifadesi kullanıyoruz , bu yüzden app / build.gradle içindeki android etiketinin içinde derleme seçeneğini 1.8 ayarlayalım.

compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

2. JSON yanıtını ayrıştırmak için Wrapper sınıfı oluşturun

Veri almak için güçlendirme ve LiveData kullanacağım ve aşağıdaki gibi JSON verileri

{
  "status": "ok",
  "error":false,
  "message":"Niximera RSS feed found",
  "data": [
   {
      "title": "Arka Plan Sınırlamaları Android Oreo",
      "pubDate": "2019-02-09 11:22:31",
      "link": "http://android.com/background-limitations-android-oreo/",
      "author": "admin",
      "thumbnail": "http://35.197.65.22/wp-content/uploads/2019/02/background-limitations-android-oreo-370x247.png",
      "description": "Eğer Oreo'da Android'de arkaplan hizmetinde tam olarak hangi sınırlamaların uygulandığını inceliyorsanız. Doğru yerdesin."
    },
   {
      "title": "ViewModel Android Örneği",
      "pubDate": "2019-02-09 11:22:31",
      "link": "http://android.com/viewmodel-android-example/",
      "author": "admin",
      "thumbnail": "http://35.197.65.22/wp-content/uploads/2019/02/viewmodel-android-example-370x247.png",
      "description": "Profesyonel seviyede android uygulama geliştirirken, göz önünde bulundurmamız gereken en yaygın şeylerden biri yapılandırma değişiklikleridir."
    },
   {
      "title": "JobIntentService ile Çalışma",
      "pubDate": "2019-02-09 11:22:31",
      "link": "http://android.com/working-with-jobintentservice/",
      "author": "admin",
      "thumbnail": "http://35.197.65.22/wp-content/uploads/2019/02/working-with-job-intent-service-370x247.png",
      "description": "Önceki yazımızda, IntentService'i Android Oreo cihazlarında kullanmanın sınırlamasını açıkladım. Android bu sorunu aşmak için JobIntentService tanıttı"
    }]
}

2.1 Sadece bir sarmalayıcı sınıfı oluşturun BlogWrapper ve aşağıdaki gibi alıcı setter

package com.niximera.livedataexample.model;

import com.google.gson.annotations.SerializedName;

import java.util.List;

@SuppressWarnings("unused")
public class BlogWrapper {

    @SerializedName("data")
    private List<Blog> mData;
    @SerializedName("error")
    private Boolean mError;
    @SerializedName("message")
    private String mMessage;
    @SerializedName("status")
    private String mStatus;

    public List<Blog> getBlog() {
        return mData;
    }

    public void setBlog(List<Blog> data) {
        mData = data;
    }

    public Boolean getError() {
        return mError;
    }

    public void setError(Boolean error) {
        mError = error;
    }

    public String getMessage() {
        return mMessage;
    }

    public void setMessage(String message) {
        mMessage = message;
    }

    public String getStatus() {
        return mStatus;
    }

    public void setStatus(String status) {
        mStatus = status;
    }

}

2.2 Şimdi Blog Öğesi için Sarıcı sınıfı oluşturun.

package com.niximera.livedataexample.model;

import com.google.gson.annotations.SerializedName;

public class Blog {

    @SerializedName("author")
    private String mAuthor;
    @SerializedName("description")
    private String mDescription;
    @SerializedName("link")
    private String mLink;
    @SerializedName("pubDate")
    private String mPubDate;
    @SerializedName("thumbnail")
    private String mThumbnail;
    @SerializedName("title")
    private String mTitle;

    public String getAuthor() {
        return mAuthor;
    }

    public void setAuthor(String author) {
        mAuthor = author;
    }

    public String getDescription() {
        return mDescription;
    }

    public void setDescription(String description) {
        mDescription = description;
    }

    public String getLink() {
        return mLink;
    }

    public void setLink(String link) {
        mLink = link;
    }

    public String getPubDate() {
        return mPubDate;
    }

    public void setPubDate(String pubDate) {
        mPubDate = pubDate;
    }

    public String getThumbnail() {
        return mThumbnail;
    }

    public void setThumbnail(String thumbnail) {
        mThumbnail = thumbnail;
    }

    public String getTitle() {
        return mTitle;
    }

    public void setTitle(String title) {
        mTitle = title;
    }

}

3. LiveData ile etkileşime geçmek için bir Depo oluşturun

Şimdilik BlogRepository adlı bir java sınıfı oluşturun ve aşağıdaki gibi değişken LiveData nesnesini bildirin.

public class BlogRepository {
    private ArrayList<Blog> movies = new ArrayList<>();
    private MutableLiveData<List<Blog>> mutableLiveData = new MutableLiveData<>();
    private Application application;
    
    public BlogRepository(Application application) {
        this.application = application;
    }

}

3.1 Uzaktan kumanda ile etkileşim için bir güçlendirme arayüzü oluşturun ve aşağıdaki yöntemleri gösterin.

Şimdi , Web Hizmeti ile etkileşime geçmek için LiveData ile güçlendirme yapın.

package com.niximera.livedataexample.service;

import com.niximera.livedataexample.model.BlogWrapper;

import retrofit2.Call;
import retrofit2.http.GET;

/**
 * Author     : Niximera
 */
public interface RestApiService {


    @GET("feed.json")
    Call<BlogWrapper> getPopularBlog();

}

3.2 Ayrıca, aşağıdaki gibi bir güçlendirme örneği oluşturun

package com.niximera.livedataexample.service;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import static com.niximera.livedataexample.BuildConfig.BASE_URL;

/**
 * Author     : Niximera
 */
public class RetrofitInstance {

    private static Retrofit retrofit = null;

    public static RestApiService getApiService() {
        if (retrofit == null) {

            retrofit = new Retrofit
                    .Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

        }
        return retrofit.create(RestApiService.class);
    }
}

3.3 Şimdi app / build.gradle dosyasını açın ve config / defaultConfig etiketi içinde BASE_URL tanımlayın

buildConfigField "String", "BASE_URL", '"http://niximera.com/xxx/"'

3.4 Şimdi BlogRepository’yi açın ve getMutableLiveData () öğesini gösterin

public MutableLiveData<List<Blog>> getMutableLiveData() {

        RestApiService apiService = RetrofitInstance.getApiService();

        Call<BlogWrapper> call = apiService.getPopularBlog();

        call.enqueue(new Callback<BlogWrapper>() {
            @Override
            public void onResponse(Call<BlogWrapper> call, Response<BlogWrapper> response) {
                BlogWrapper mBlogWrapper = response.body();
                if (mBlogWrapper != null && mBlogWrapper.getBlog() != null) {
                    movies = (ArrayList<Blog>) mBlogWrapper.getBlog();
                    mutableLiveData.setValue(movies);
                }
            }

            @Override
            public void onFailure(Call<BlogWrapper> call, Throwable t) {

            }
        });


        return mutableLiveData;
    }

3.5 BlogRepository sınıfının tamamı buna benzer

package com.niximera.livedataexample.model;

import android.app.Application;
import android.arch.lifecycle.MutableLiveData;

import com.niximera.livedataexample.service.RestApiService;
import com.niximera.livedataexample.service.RetrofitInstance;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Author     : Niximera
 */
public class BlogRepository {
    private ArrayList<Blog> movies = new ArrayList<>();
    private MutableLiveData<List<Blog>> mutableLiveData = new MutableLiveData<>();
    private Application application;

    public BlogRepository(Application application) {
        this.application = application;
    }

    public MutableLiveData<List<Blog>> getMutableLiveData() {

        RestApiService apiService = RetrofitInstance.getApiService();

        Call<BlogWrapper> call = apiService.getPopularBlog();

        call.enqueue(new Callback<BlogWrapper>() {
            @Override
            public void onResponse(Call<BlogWrapper> call, Response<BlogWrapper> response) {
                BlogWrapper mBlogWrapper = response.body();
                if (mBlogWrapper != null && mBlogWrapper.getBlog() != null) {
                    movies = (ArrayList<Blog>) mBlogWrapper.getBlog();
                    mutableLiveData.setValue(movies);
                }
            }

            @Override
            public void onFailure(Call<BlogWrapper> call, Throwable t) {

            }
        });


        return mutableLiveData;
    }
}

4. ViewModel’i oluşturun

MainViewModel adında bir ViewModel alt sınıfı oluşturun (Ana, oturum açma etkinliği için LoginViewModel’i kullanabileceğimiz gibi, bir etkinlik adından alıyor). MainViewModel sınıfı, AndroidViewModel’i genişletir. Yani temelde Android’de ViewModel için iki üst sınıf. ViewModel ve AndroidViewModel. farklı, yalnızca Bağlamın görünürlüğüdür. AndroidViewModel, burada AndroidViewModel kullanarak kullandığımız bir uygulama içeriğine sahiptir.

package com.niximera.livedataexample.viewmodel;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.support.annotation.NonNull;

import com.niximera.livedataexample.model.Blog;
import com.niximera.livedataexample.model.BlogRepository;

import java.util.List;

/**
 * Author     : Niximera
 */
public class MainViewModel extends AndroidViewModel {
    private BlogRepository movieRepository;

    public MainViewModel(@NonNull Application application) {
        super(application);
        movieRepository = new BlogRepository(application);
    }

    public LiveData<List<Blog>> getAllBlog() {
        return movieRepository.getMutableLiveData();
    }


}

Şimdi LiveData ve Görünüm Modeli bölümü kullanıma hazır.

5. Blog öğesi için bir XML düzeni oluşturun

Bu demoda, RecyclerView üzerinden blog listesini gösteriyoruz. Şimdi blog_item.xml adlı blog öğesi için bir düzen oluşturun.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="16dp"
    android:background="#fff"
    android:padding="8dp">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="8dp"
        android:fontFamily="@font/montserrat"
        android:gravity="left"
        android:includeFontPadding="true"
        android:letterSpacing="-0.02"
        android:lineSpacingExtra="5sp"
        android:text="Dagger2 Android Example"
        android:textAlignment="gravity"
        android:textColor="@color/navy"
        android:textSize="16sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/ivThumbnail"
        android:layout_width="0dp"
        android:layout_height="210dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:scaleType="fitXY"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvTitle"
        tools:srcCompat="@tools:sample/avatars" />

    <TextView
        android:id="@+id/tvDescription"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:fontFamily="@font/montserrat"
        android:text="http://androidwave.com/dagger2-android-example/"
        android:textColor="@color/navy"
        android:textSize="14sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/ivThumbnail" />

    <TextView
        android:id="@+id/tvLink"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:fontFamily="@font/montserrat"
        android:text="http://androidwave.com/dagger2-android-example/"
        android:textColor="@color/windows_blue"
        android:textSize="15sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvDescription" />
</android.support.constraint.ConstraintLayout>

6. BlogAdapter adlı bir RecyclerView adaptörü oluşturun

package com.niximera.livedataexample.ui;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.niximera.livedataexample.R;
import com.niximera.livedataexample.model.Blog;

import java.util.List;

/**
 * Author     : Niximera
 */
public class BlogAdapter extends RecyclerView.Adapter<BaseViewHolder> {
    private static final String TAG = "BlogAdapter";

    private List<Blog> mBlogList;

    public BlogAdapter(List<Blog> blogList) {
        mBlogList = blogList;
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        holder.onBind(position);
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(
                LayoutInflater.from(parent.getContext()).inflate(R.layout.blog_item, parent, false));


    }

    @Override
    public int getItemViewType(int position) {
        return 0;
    }

    @Override
    public int getItemCount() {
        if (mBlogList != null && mBlogList.size() > 0) {
            return mBlogList.size();
        } else {
            return 0;
        }
    }

    public class ViewHolder extends BaseViewHolder {

        ImageView ivThumbnail;
        TextView tvTitle;
        TextView tvDescription;
        TextView tvLink;

        public ViewHolder(View itemView) {
            super(itemView);
            ivThumbnail = itemView.findViewById(R.id.ivThumbnail);
            tvTitle = itemView.findViewById(R.id.tvTitle);
            tvDescription = itemView.findViewById(R.id.tvDescription);
            tvLink = itemView.findViewById(R.id.tvLink);

        }

        protected void clear() {
            ivThumbnail.setImageDrawable(null);
            tvTitle.setText("");
            tvLink.setText("");
        }

        public void onBind(int position) {
            super.onBind(position);

            final Blog mBlog = mBlogList.get(position);

            if (mBlog.getThumbnail() != null) {
                Glide.with(itemView.getContext())
                        .load(mBlog.getThumbnail())
                        .into(ivThumbnail);
            }

            if (mBlog.getTitle() != null) {
                tvTitle.setText(mBlog.getTitle());
            }

            if (mBlog.getDescription() != null) {
                tvDescription.setText(mBlog.getDescription());
            }

            if (mBlog.getLink() != null) {
                tvLink.setText(mBlog.getLink());
            }

            tvLink.setOnClickListener(v -> {
                if (mBlog.getLink() != null) {
                    try {
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        intent.addCategory(Intent.CATEGORY_BROWSABLE);
                        intent.setData(Uri.parse(mBlog.getLink()));
                        itemView.getContext().startActivity(intent);
                    } catch (Exception e) {
                        Log.e(TAG, "onClick: Image url is not correct");
                    }
                }
            });
        }
    }

}

6.1 BaseViewHolder

package com.niximera.livedataexample.ui;

import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Author     : Niximera
 */
public abstract class BaseViewHolder extends RecyclerView.ViewHolder {

    private int mCurrentPosition;

    public BaseViewHolder(View itemView) {
        super(itemView);
    }

    protected abstract void clear();

    public void onBind(int position) {
        mCurrentPosition = position;
        clear();
    }

    public int getCurrentPosition() {
        return mCurrentPosition;
    }
}

7. Şimdi activity_main.xml dosyasını açın ve SwipeRefreshLayout içine RecyclerView ekleyin

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f2f2f2"
    android:padding="8dp"
    tools:context=".ui.MainActivity">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swiperefresh"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">


        <android.support.v7.widget.RecyclerView
            android:id="@+id/blogRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.ConstraintLayout>

8. Şimdi MainActivity’yi açın ve işlemi izleyin

  1. findViewById yardımıyla SwipeRefreshLayout, RecyclerView gibi görünümleri başlat
  2. ViewModelProviders’in yardımıyla MainViewModel örneğini oluşturun
  3. <Mlog>> Listesini gözlemleyen ViewModel’de getAllBlog () gözlemcisi uygulandı
  4. Sonunda BlogAadapter’ı hazırlayın ve RecyclerView’a ayarlayın
  5. Sonunda manifestte internet izni ekleyin (<uses-allow android: name = ”android.permission.INTERNET” />)

Son olarak, MainActivity kaynak kodu aşağıdaki gibi görünüyor

package com.niximera.livedataexample.ui;

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.niximera.livedataexample.R;
import com.niximera.livedataexample.model.Blog;
import com.niximera.livedataexample.viewmodel.MainViewModel;

import java.util.List;

public class MainActivity extends AppCompatActivity {


    RecyclerView mRecyclerView;
    SwipeRefreshLayout swipeRefresh;
    private MainViewModel mainViewModel;

    BlogAdapter mBlogAdapter;

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

        initializationViews();
        mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
        getPopularBlog();
        // lambda expression
        swipeRefresh.setOnRefreshListener(() -> {
            getPopularBlog();
        });
    }

    private void initializationViews() {
        swipeRefresh = findViewById(R.id.swiperefresh);
        mRecyclerView = findViewById(R.id.blogRecyclerView);
    }

    public void getPopularBlog() {
        swipeRefresh.setRefreshing(true);
        mainViewModel.getAllBlog().observe(this, new Observer<List<Blog>>() {
            @Override
            public void onChanged(@Nullable List<Blog> blogList) {
                swipeRefresh.setRefreshing(false);
                prepareRecyclerView(blogList);
            }
        });
        /**
         * Replace this statement with lambda expression
         * For using set you have to set following lines in app/build.gradle
             // add below line
             compileOptions {
             sourceCompatibility JavaVersion.VERSION_1_8
             targetCompatibility JavaVersion.VERSION_1_8
             }
             // reduce line of code
             mainViewModel.getAllBlog().observe(this, blogList -> prepareRecyclerView(blogList));

         */

    }

    private void prepareRecyclerView(List<Blog> blogList) {

        mBlogAdapter = new BlogAdapter(blogList);
        if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        } else {
            mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));

        }
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mRecyclerView.setAdapter(mBlogAdapter);
        mBlogAdapter.notifyDataSetChanged();
    }
}

Yukarıdaki tüm adımları takip ettikten sonra, projeyi derleyin ve ÇALIŞTIRIN. Çıktı beklendiği gibi olacak. Herhangi bir sorunuz varsa, aşağıdaki yorum bölümünde sormayı çekinmeyin.

Comments

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

GIPHY App Key not set. Please check settings

Yükleniyor…

0

Ne düşünüyorsun?

Swift: Enum Kullanımı

Hayatınızı kolaylaştıracak e-ticaret muhasebesi için 4 ipucu