Fyd Rose
Fyd Rose

Reputation: 21

Slow and laggy custom listView

I have a custom listView with many texts and images (about 60 images) and, when scrolled, it is very laggy. I've added a ViewHolder to my code, but it still lag. I know that the solution is probably to use a background Thread, but i don't know how to do this. Can you guys help me?

CustomAdapter.java:

public class CustomAdapter extends RecyclerView.Adapter<CustomViewHolder> {

    //Attributi:
    private Context context;
    private int[] immagineDio;
    private String[] nomeDio;

    //Costruttori:
    public CustomAdapter(Context context, int[] immagineDio, String[] nomeDio){
        this.context = context;
        this.immagineDio = immagineDio;
        this.nomeDio = nomeDio;
    }

    //Metodi di istanza:
    @NonNull
    @Override
    public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return CustomViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull CustomViewHolder holder, int position) {
        holder.bind(immagineDio[position], nomeDio[position]);
    }

    @Override
    public int getItemCount() {
        return nomeDio.length;
    }

}

CustomViewHolder.java:

 public class CustomViewHolder extends RecyclerView.ViewHolder {

     ImageView mFlag;
     TextView mName;

     public CustomViewHolder(@NonNull View itemView) {
         super(itemView);
         mFlag = itemView.findViewById(R.id.imageView);
         mName = itemView.findViewById(R.id.textView);
     }

     //binding data with UI
     void bind(int imageId, String name) {
         mFlag.setImageResource(imageId);
         mName.setText(name);
     } }

ListViewActivity.java:

 public class ListViewActivity extends AppCompatActivity {
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.listview_layout);

         String[] nomeDei = {"Baldr","Borr","Bragi","Dagr","Dellingr","Eir","Eostre","Forseti","Freya","Freyr","Frigg","Fulla","Gefjun","Gerðr","Gullveig","Heimdallr","Hel","Hermóðr","Höðr","Hœnir","Iðunn","Itreksjóð","Jǫrð","Kvasir","Lóðurr","Lofn","Logi","Lýtir","Máni","Mímir","Móði","Nanna","Njörun","Njörðr","Nótt","Óðr","Rán","Ríg","Sága","Sif","Signe","Sigyn","Sinfjötli","Sjöfn","Skaði","Skirnir","Snotra","Sól","Syn","Thor","Týr","Ullr","Váli","Vár","Ve","Viðarr","Víli","Vör"};
         int[] immagineDei = {
                 R.drawable.profilo_baldr, 
                 R.drawable.profilo_borr,
                 R.drawable.profilo_bragi,
                 R.drawable.profilo_dagr,
                 R.drawable.profilo_dellingr,
                 R.drawable.profilo_eir, 
                 R.drawable.profilo_eostre,
                 R.drawable.profilo_forseti, 
                 R.drawable.profilo_freya, 
                 R.drawable.profilo_freyr,
                 R.drawable.profilo_frigg,
                 R.drawable.profilo_fulla,
                 R.drawable.profilo_gefjun,
                 R.drawable.profilo_geror,
                 R.drawable.profilo_gullveig,
                 R.drawable.profilo_heimdallr,
                 R.drawable.profilo_hel, 
                 R.drawable.profilo_hermoor,
                 R.drawable.profilo_hoor,
                 R.drawable.profilo_hoenir,
                 R.drawable.profilo_iounn,
                 R.drawable.profilo_itreksjoo,
                 R.drawable.profilo_joro,
                 R.drawable.profilo_kvasir,
                 R.drawable.profilo_loourr,
                 R.drawable.profilo_lofn,
                 R.drawable.profilo_logi,
                 R.drawable.profilo_lytir,
                 R.drawable.profilo_mani,
                 R.drawable.profilo_mimir,
                 R.drawable.profilo_modi,
                 R.drawable.profilo_nanna,
                 R.drawable.profilo_njorun,
                 R.drawable.profilo_njoror,
                 R.drawable.profilo_nott,
                 R.drawable.profilo_oor,
                 R.drawable.profilo_ran,
                 R.drawable.profilo_rig,
                 R.drawable.profilo_saga,
                 R.drawable.profilo_sif,
                 R.drawable.profilo_signe,
                 R.drawable.profilo_sigyn,
                 R.drawable.profilo_sinfjotli,
                 R.drawable.profilo_sjofn,
                 R.drawable.profilo_skaoi,
                 R.drawable.profilo_skirnir,
                 R.drawable.profilo_snotra,
                 R.drawable.profilo_sol,
                 R.drawable.profilo_syn,
                 R.drawable.profilo_thor,
                 R.drawable.profilo_tyr,
                 R.drawable.profilo_ullr, 
                 R.drawable.profilo_vali,
                 R.drawable.profilo_var,
                 R.drawable.profilo_ve,
                 R.drawable.profilo_vidar,
                 R.drawable.profilo_vili,
                 R.drawable.profilo_vor,
         };

         ListView listViewReference = findViewById(R.id.listView);
         CustomAdapter customAdapter = new CustomAdapter(ListViewActivity.this, immagineDei, nomeDei);
         listViewReference.setAdapter(customAdapter); //this line gives an error
     } }

listview_layout.xml:

 <?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"
     tools:context=".HomeActivity">


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

Upvotes: 0

Views: 382

Answers (3)

AIMIN PAN
AIMIN PAN

Reputation: 1675

If you are already using ViewHolder, there should not be many performance difference between ListView and RecyclerView.

Instead you should something like Glide which loads at another thread. Code should be very simple, just replace

imageView.setImageResource(R.drawable.some)

with

Glide.with(activity).load(R.drawable.some).into(imageView)

More info:

to use Glide, you need to add Glide library to your app's build.gradle file:

repositories {
  mavenCentral()
  google()
}

dependencies {
  implementation 'com.github.bumptech.glide:glide:4.9.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
}

Upvotes: 0

Birju Vachhani
Birju Vachhani

Reputation: 6373

You can convert it into RecyclerView. Here's how.

CustomAdapter.java

public class CustomAdapter extends RecyclerView.Adapter<CustomViewHolder> {

    private Context context;
    private int[] immagineDio;
    private String[] nomeDio;

    public CustomAdapter(Context context, int[] immagineDio, String[] nomeDio){
        this.context = context;
        this.immagineDio = immagineDio;
        this.nomeDio = nomeDio;
    }

    @NonNull
    @Override
    public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return CustomViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull CustomViewHolder holder, int position) {
        holder.bind(immagineDio[position],nomeDio[position]);
    }

    @Override
    public int getItemCount() {
        return nomeDio.length;
    }
}

CustomViewHolder.java

public class CustomViewHolder extends RecyclerView.ViewHolder {

    ImageView mFlag;
    TextView mName;

    public CustomViewHolder(@NonNull View itemView) {
        super(itemView);
        mFlag = itemView.findViewById(R.id.imageView);
        mName = itemView.findViewById(R.id.textView);
    }

    // binding data with ui
    void bind(int imageId, String name) {
        mFlag.setImageResource(imageId);
        mName.setText(name);
    }
}

Upvotes: 0

med.Hamdan
med.Hamdan

Reputation: 300

If your app needs to display a scrolling list of elements based on large data sets (or data that frequently changes), you should use RecyclerView.

Upvotes: 0

Related Questions