Listview тормозит, и я не могу это исправить

У меня есть список, в котором я назначаю изображение для каждого элемента в списке. Дело в том, что я уже сделал, что приложение будет загружать только 10 строк за раз, а элементы складываются, когда пользователь прокручивает, я включаю аппаратное ускорение, я сжимал и уменьшал размер изображений до крошечных размеров, но независимо от того, что я делал в режиме просмотра списка все еще тормозит.

Я попытался поискать в Интернете и не мог понять, как реализовать что-либо в моем сценарии или что-нибудь еще, что могло бы ускорить процесс. Вот мой BaseAdapter:

  public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater layoutInflater = ((Activity)context).getLayoutInflater();
    View view = layoutInflater.inflate(R.layout.library_layout, parent, false);
    view.setBackgroundColor(Color.parseColor("#FFFFFF"));
    final GamesLibrary gl = objects.get(position);
    TextView title = (TextView)view.findViewById(R.id.titleId);
    TextView excerpt = (TextView)view.findViewById(R.id.excerptId);
    ImageView imageView = view.findViewById(R.id.listViewImageView);
    ImageButton commBt = view.findViewById(R.id.goToCommLv);
    final TextView author = view.findViewById(R.id.authorId);
    final CheckBox likeBox = view.findViewById(R.id.likeIconLv);
    ImageButton sharingButton = view.findViewById(R.id.shareButtonLv);
    final SharedPreferences sp;
    sp=context.getSharedPreferences("likes", 0);
    final SharedPreferences.Editor editor = sp.edit();
    String[] allFavsIds =SpIdstoArr(sp.getString("ids", ""));
    final String id = String.valueOf(gl.getId());
    SharedPreferences sp4 =context.getSharedPreferences("LocalLogInData", 0);
    String uname= sp4.getString("Uname","dsufhsiudhfsdef");

    if (gl.getTitle().contains(uname))
    {
        Log.d("aw12","aw12");
        commBt.setClickable(false);
        commBt.setEnabled(false);
        commBt.setAlpha(0.5f);
    }






    title.setText(gl.getTitle());
    Log.d("glgl",gl.getTitle());
    excerpt.setText(gl.getExcerpt());
    author.setText("by " + gl.getAuthor());
    String FirstTag = "";
    try {
        FirstTag = gl.getTags()[0];
    }
    catch (Exception e)
    {
        Log.d("gameLibAdap", e.toString());}
    if (FirstTag != null) {
        if (FirstTag.equals("מערך אכפתיות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.care));
        else if (FirstTag.equals("מערך חגים"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.holidays));
        else if (FirstTag.equals("מערך חשיבה אחרת"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.thinkdifferent2));
        else if (FirstTag.equals("מערך גיבוש והנאה"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.fun));
        else if (FirstTag.equals("מערך חברות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.friendship));
        else if (FirstTag.equals("מערך סובלנות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.tolerance));
        else if (FirstTag.equals("מערך אחריות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.responsibility));
        else if (FirstTag.equals("פעולות ללא מערך"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.logo1));
        else if (FirstTag.equals("מערך שיתוף פעולה"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.teamwork));
        else if (FirstTag.equals("מערך חוץ וטבע"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.nature));
        else if (FirstTag.equals("מערך מנהיגות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.leading));
        else if (FirstTag.equals("מערך סבלנות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.patience));
        else if (FirstTag.equals("מערך יוזמה"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.yozma));
        else if (FirstTag.equals("מערך שוויון"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.equlity));
        else if (FirstTag.equals("מערך הישגים אישיים"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.personalachivements));
        else if (FirstTag.equals("מערך עידן מודרני"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.modern));
        else if (FirstTag.equals("ערך שוויון"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.equlity));
        else if (FirstTag.equals("ערך ישראליות/ ציונות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.zionism));
        else if (FirstTag.equals("מערך מודעות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.awareness2));
        else if (FirstTag.equals("מערך חשיבה אחרת"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.thinkdifferent2));
        else if (FirstTag.equals("מערך הישגים אישיים"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.personalachivements));
        else if (FirstTag.equals("ערך קבלת השונה"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.acceptance));
        else if (FirstTag.equals("אלכוהול וסמים"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.alcohol));
        else if (FirstTag.equals("ללא הכנה מראש"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.unprepared));
        else if (FirstTag.equals("מערך היכרות"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.meeting));
        else if (FirstTag.equals("מערך הדרכה"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.guiding));
        else if (FirstTag.equals("מערך יום הזיכרון"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.memorial));
        else if (FirstTag.equals("מערך יום הזיכרון לשואה"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.holocaustmemorial));
        else if (FirstTag.equals("מערך שינוי"))
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.change));
        else
            imageView.setImageDrawable(context.getApplicationContext().getResources().getDrawable(R.drawable.logo1));

    }


    likeBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)
        {

            if (isChecked)
            {
                String value = sp.getString("ids", "");
                Log.d("ids", value);
                value += "," + id + "/";
                editor.putString("ids", value).commit();
                Log.d("ids", value);
                Log.d("ids", sp.getString("ids", ""));
            }
            if (!isChecked)
            {
                String value = sp.getString("ids", "");
                String replaceString= value.replace("," + id + "/", "");
                editor.putString("ids", replaceString).commit();
                Log.d("ids2", sp.getString("ids", ""));
            }
            Log.d("ids3", sp.getString("ids", ""));

        }
    });
    if (checkMatch(String.valueOf(id),allFavsIds))
        likeBox.setChecked(true);
    else
        likeBox.setChecked(false);

    commBt.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Intent in = new Intent(context,CommentActivity.class);
            in.putExtra("Json", gl.getCommJson());
            in.putExtra("pId", String.valueOf(id));
            in.putExtra("cats", gl.getCategories());
            context.startActivity(in);
        }
    });



    sharingButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            shareIt(gl.getUrl(),gl.getTitle());
        }
    });






    return view;}

Я объясню, чтобы мой код не сбивал с толку, я просто назначаю тексты и изображения для каждого элемента по его свойствам, есть также кнопка «Нравится» и кнопка комментария, которые переводят пользователя на страницу комментариев. Вы, ребята, знаете, что я могу сделать?

Я начинающий.

Обновление: код проверки совпадения:

public static boolean checkMatch(String id, String[] favIds)
{
    boolean b = false;
    for (int i = 0; i <favIds.length; i++)
    {
        if (favIds[i].equals(id)) {
            b = true;
            favIds[i] = "";
        }
    }
    return b;
}

Новый код - ViewHlder:

class MyviewHolder
{
    TextView title, excerpt,author;
    ImageView imageView, profilepic;
    ImageButton commBt,sharingButton;
    CheckBox likeBox;
    MyviewHolder(View v)
    {
         title = (TextView)v.findViewById(R.id.titleId);
         excerpt = (TextView)v.findViewById(R.id.excerptId);
         imageView =(ImageView) v.findViewById(R.id.listViewImageView);
         commBt = (ImageButton) v.findViewById(R.id.goToCommLv);
          author =(TextView) v.findViewById(R.id.authorId);
          likeBox = (CheckBox) v.findViewById(R.id.likeIconLv);
         sharingButton = (ImageButton) v.findViewById(R.id.shareButtonLv);
         profilepic = v.findViewById(R.id.saProfilePic);
         profilepic.setVisibility(View.VISIBLE);
    }

}

Новый код - getView:

@Override
public View getView(int position, View convertView, ViewGroup parent)
{



    View view =convertView;
    MyviewHolder viewHolder=null;

    if (view==null)
    {
        LayoutInflater layoutInflater = ((Activity)context).getLayoutInflater();
        view = layoutInflater.inflate(R.layout.library_layout, parent, false);
        viewHolder=new MyviewHolder(view);
        view.setTag(viewHolder);
        Log.d("gg22","creating");
        view.setBackgroundColor(Color.parseColor("#FFFFFF"));
    }
    else
    {
        viewHolder = (MyviewHolder) view.getTag();
        Log.d("gg22","recycling");
    }



    final GamesLibrary gl = objects.get(position);

    viewHolder.title.setText(gl.getTitle());
    viewHolder.excerpt.setText(gl.getExcerpt());
    viewHolder.imageView.setImageResource(R.drawable.logo1);
    viewHolder.author.setText("by " + gl.getAuthor());



    final SharedPreferences sp;
    sp=context.getSharedPreferences("likes", 0);
    final SharedPreferences.Editor editor = sp.edit();
    String[] allFavsIds =SpIdstoArr(sp.getString("ids", ""));
    final String id = String.valueOf(gl.getId());

    if (gl.getTitle().contains(UName()))
    {
        viewHolder.commBt.setClickable(false);
        viewHolder.commBt.setEnabled(false);
        viewHolder.commBt.setAlpha(0.5f);
    }


    int imageviewRID;






    String FirstTag = "";
    try {
        FirstTag = gl.getTags()[0];
    }
    catch (Exception e)
    {
        Log.d("gameLibAdap", e.toString());}

    if (FirstTag != null) {
        if (FirstTag.equals("מערך אכפתיות"))
            imageviewRID=R.drawable.care;
        else if (FirstTag.equals("מערך חגים"))
            imageviewRID=R.drawable.holidays;
        else if (FirstTag.equals("מערך חשיבה אחרת"))
            imageviewRID=R.drawable.thinkdifferent2;
        else if (FirstTag.equals("מערך גיבוש והנאה"))
            imageviewRID=R.drawable.fun;
        else if (FirstTag.equals("מערך חברות"))
            imageviewRID=R.drawable.friendship;
        else if (FirstTag.equals("מערך סובלנות"))
            imageviewRID=R.drawable.tolerance;
        else if (FirstTag.equals("מערך אחריות"))
            imageviewRID=R.drawable.responsibility;
        else if (FirstTag.equals("פעולות ללא מערך"))
            imageviewRID=R.drawable.logo1;
        else if (FirstTag.equals("מערך שיתוף פעולה"))
            imageviewRID=R.drawable.teamwork;
        else if (FirstTag.equals("מערך חוץ וטבע"))
            imageviewRID=R.drawable.nature;
        else if (FirstTag.equals("מערך מנהיגות"))
            imageviewRID=R.drawable.leading;
        else if (FirstTag.equals("מערך סבלנות"))
            imageviewRID=R.drawable.patience;
        else if (FirstTag.equals("מערך יוזמה"))
            imageviewRID=R.drawable.yozma;
        else if (FirstTag.equals("מערך שוויון"))
            imageviewRID=R.drawable.equlity;
        else if (FirstTag.equals("מערך הישגים אישיים"))
            imageviewRID=R.drawable.personalachivements;
        else if (FirstTag.equals("מערך עידן מודרני"))
            imageviewRID=R.drawable.modern;
        else if (FirstTag.equals("ערך שוויון"))
            imageviewRID=R.drawable.equlity;
        else if (FirstTag.equals("ערך ישראליות/ ציונות"))
            imageviewRID=R.drawable.zionism;
        else if (FirstTag.equals("מערך מודעות"))
            imageviewRID=R.drawable.awareness2;
        else if (FirstTag.equals("מערך חשיבה אחרת"))
            imageviewRID=R.drawable.thinkdifferent2;
        else if (FirstTag.equals("מערך הישגים אישיים"))
            imageviewRID=R.drawable.personalachivements;
        else if (FirstTag.equals("ערך קבלת השונה"))
            imageviewRID=R.drawable.acceptance;
        else if (FirstTag.equals("אלכוהול וסמים"))
            imageviewRID=R.drawable.alcohol;
        else if (FirstTag.equals("ללא הכנה מראש"))
            imageviewRID=R.drawable.unprepared;
        else if (FirstTag.equals("מערך היכרות"))
            imageviewRID=R.drawable.meeting;
        else if (FirstTag.equals("מערך הדרכה"))
            imageviewRID=R.drawable.guiding;
        else if (FirstTag.equals("מערך יום הזיכרון"))
            imageviewRID=R.drawable.memorial;
        else if (FirstTag.equals("מערך יום הזיכרון לשואה"))
            imageviewRID=R.drawable.holocaustmemorial;
        else if (FirstTag.equals("מערך שינוי"))
            imageviewRID=R.drawable.change;
        else
            imageviewRID=R.drawable.logo1;
        viewHolder.imageView.setImageResource(imageviewRID);
    }


    viewHolder.likeBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)
        {

            if (isChecked)
            {
                String value = sp.getString("ids", "");
                Log.d("ids", value);
                value += "," + id + "/";
                editor.putString("ids", value).apply();
                Log.d("ids", value);
                Log.d("ids", sp.getString("ids", ""));
            }
            if (!isChecked)
            {
                String value = sp.getString("ids", "");
                String replaceString= value.replace("," + id + "/", "");
                editor.putString("ids", replaceString).apply();
                Log.d("ids2", sp.getString("ids", ""));
            }
            Log.d("ids3", sp.getString("ids", ""));

        }
    });
    if (checkMatch(String.valueOf(id),allFavsIds))
        viewHolder.likeBox.setChecked(true);
    else
        viewHolder.likeBox.setChecked(false);

    viewHolder.commBt.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Intent in = new Intent(context,CommentActivity.class);
            in.putExtra("Json", gl.getCommJson());
            in.putExtra("pId", String.valueOf(id));
            in.putExtra("cats", gl.getCategories());
            context.startActivity(in);
        }
    });



    viewHolder.sharingButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            shareIt(gl.getUrl(),gl.getTitle());
        }
    });






    return view;
}

Вы можете попробовать закомментировать некоторые части, чтобы увидеть, ускоряет ли это процесс. Я бы заподозрил вызовы SharedPreferences и создание объекта Editor. Лучше отложить создание редактора на слушателя там, где он нужен. Также вызовы методов gl могут замедлять, а могут и не замедлять работу. Попробуйте сами. Для сложной компоновки также может оказаться полезным повторное использование convertView.

Michael Butscher 05.11.2018 00:28
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
77
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Это можно улучшить с помощью Посмотреть шаблон держателя. Вместо того, чтобы создавать новое представление и выполнять всю стандартную настройку для каждого элемента, повторно используйте представления, которые были ранее созданы для элементов, которые теперь находятся за пределами видимой области.

Обратите внимание, что на этот вопрос уже был дан ответ несколько раз. Обратите внимание на следующие вопросы и ответы:

Другие вещи, которые я бы изменил, чтобы сделать это более производительным:

  • Удалите использование исключений для «нормального» поведения. Код обычно оптимизирован для неисключительного потока (необходима цитата), поэтому попадание в блок catch часто может быть проблемой.
  • Переключитесь с SharedPreferences.Editor.commit() на SharedPreferences.Editor.apply(). Согласно документации, commit() выполняет синхронную запись на диск, в то время как apply() записывает только в структуру в памяти и записывает на диск асинхронно. Проблема здесь может заключаться в том, что вы сначала создаете слушателя, а затем вызываете setChecked. Проверьте, вызывается ли слушатель при вызове setChecked, и переключите создание слушателя и setChecked в коде.
  • Посмотрите, не проблема ли длинный if ... else ... if. Попробуйте карту.
  • Не создавайте новых слушателей для каждого нового элемента. Создайте их один раз для каждого ViewHolder, установите элемент gl на ViewHolder как поле и обратитесь к полю в слушателе.

Если вы хотите проявить фантазию, используйте Профайлер Android, чтобы измерить производительность метода и посмотреть, на что вы тратили большую часть времени.

Да, спасибо! Я сейчас пытаюсь реализовать это, надеюсь, у меня это получится.

amir Asaf 05.11.2018 09:49

Привет! Я реализовал ViewHolder, и он полностью работает, но представление списка все еще немного тормозит, вы знаете, что еще я могу сделать?

amir Asaf 05.11.2018 11:11

Основываясь на вашем исходном коде, я хотел бы посмотреть, являются ли следующие проблемы проблемой: objects.get(), чтение с SharedPreferences, длинный блок if .. else if. Попробуйте закомментировать их и заменить каким-нибудь кодом-заглушкой, чтобы увидеть, что они являются причиной задержки. Если вы хотите быть более навороченным, попробуйте Профайлер Android

Maik 05.11.2018 19:02

Также проблема может быть в SharedPreferences.Editor.commit(). В справочном документе говорится, что он все еще синхронно ожидает записи изменений на диск. Похоже, вы записываете на диск всякий раз, когда в список добавляется новый элемент. Попробуйте SharedPreferences.Editor.apply()

Maik 05.11.2018 19:09

Я немного обновил свой ответ. См. Мой маркер о SharedPreferences. Я считаю, что onCheckedChanged () вызывается, когда вы вызываете setChecked (), поэтому вы получаете блокирующую запись на диск для каждого элемента.

Maik 06.11.2018 01:27

Привет, большое вам спасибо! То, что вы предложили с помощью настроек View Holder и Shared, значительно увеличило приложение, хотя оно все еще немного тормозит. Я пытаюсь применить ваше новое предложение, но я не могу понять третье предложение. У вас есть какой-нибудь пример или зацепка, которые вы можете мне показать? Спасибо!

amir Asaf 06.11.2018 11:54

И ваш блок if else, и функция checkMatch() каждый раз перебирают N элементов, т.е. он должен выполнять N сравнений. Карта (например, HashMap в Java) позволяет вам делать то же самое с помощью всего одного сравнения. ... Хотя ускорение может быть не таким большим (по другим причинам), оно может дать вам еще один небольшой импульс. Лучше всего измерить и посмотреть, действительно ли это предложение снижает затраты времени выполнения.

Maik 06.11.2018 16:18

Как уже упоминал Майкл Бутчер, вам обязательно стоит заглянуть в класс GamesLibrary. Если это ваш, у вас есть шанс значительно улучшить, переместив длительные задачи в фоновый поток вместо использования потока пользовательского интерфейса.

Кроме того, я хотел бы дать вам несколько советов по стилю кода.

  1. Вы можете использовать switch-block вместо всех ваших блоков else if. Это значительно сократит ваш код и сделает его более читабельным.
  2. Для строк или других значений, которые вы часто используете и которые не меняются, используйте константы. (например, все ваши ключи SharedPreferences). Это отнимет у вас много работы, когда вам придется изменить некоторые из этих значений.
  3. Вы также должны использовать предоставленные константы, такие как Context.MODE_PRIVATE в getSharedPreferences (). Разборчивость кода.

Вы должны использовать ViewHolder ссылка

В item_listview.xml, если установлен фон для изображения, удалите его

Другие вопросы по теме