WedX - журнал о программировании и компьютерных науках

Динамическое добавление элементов в ListView

Я работаю над ListView в Android. Я знаю, как заполнить андроид ListView обычным способом. Но предположим, что у нас есть такой класс, как показано ниже, который содержит два TextView, Button и ProgressBar. Я объявил RelativeLayout и успешно добавил все представления в этот макет. (Проверено с использованием setContentView(new ListViewItem(this).getLayout());, в основном все в порядке).

public class ListViewItem {
    public ListViewItem(Context context) {
        this.M_speedTextView = new TextView(context);
        this.M_nameTextView = new TextView(context);
        this.M_progressBar = new ProgressBar(context, null,
                android.R.attr.progressBarStyleHorizontal);
        this.M_activityButton = new Button(context);
        this.M_layout = new RelativeLayout(context);

        this.M_speedTextView.setId(new Random().nextInt());
        this.M_nameTextView.setId(new Random().nextInt());
        this.M_progressBar.setId(new Random().nextInt());
        this.M_activityButton.setId(new Random().nextInt());

        this.M_layout.setId(new Random().nextInt());
    }

    public void setSpeed(int speed) {
        this.M_speedTextView.setText(Integer.toString(speed));
    }

    public void setName(String name) {
        this.M_nameTextView.setText(name);
    }

    public void setProgress(int progress) {
        this.M_progressBar.setProgress(progress);
    }

    public void setButtonText(String text) {
        this.M_activityButton.setText(text);
    }

    public RelativeLayout getLayout() {
        // Layout setting
        this.M_layout.setLayoutParams(new LayoutParams(
                LayoutParams.FILL_PARENT, 50));
        this.M_layout.setBackgroundResource(android.R.color.transparent);

        // Name Text setting
        LayoutParams nameTextParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        nameTextParams.setMargins(5, 10, 0, 0);
        nameTextParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 1);
        nameTextParams.addRule(RelativeLayout.LEFT_OF,
                this.M_speedTextView.getId());

        this.M_nameTextView.setTextSize(15);
        this.M_nameTextView.setText("TextView");
        this.M_nameTextView.setSingleLine();
        this.M_nameTextView.setEllipsize(TruncateAt.END);

        this.M_layout.addView(this.M_nameTextView, nameTextParams);

        // Activity Button setting
        LayoutParams activityParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        activityParams.setMargins(0, 5, 5, 0);
        activityParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 1);
        activityParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1);

        this.M_activityButton.setText("Start");

        this.M_layout.addView(this.M_activityButton, activityParams);

        // ProgressBar setting
        LayoutParams progressParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        progressParams.addRule(RelativeLayout.ALIGN_BOTTOM,
                this.M_activityButton.getId());
        progressParams.addRule(RelativeLayout.ALIGN_LEFT,
                this.M_nameTextView.getId());
        progressParams.addRule(RelativeLayout.BELOW,
                this.M_nameTextView.getId());
        progressParams.addRule(RelativeLayout.LEFT_OF,
                this.M_activityButton.getId());

        this.M_layout.addView(this.M_progressBar, progressParams);

        // Speed TextView setting
        LayoutParams speedParam = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT);
        speedParam.addRule(RelativeLayout.ALIGN_BASELINE,
                this.M_nameTextView.getId());
        speedParam.addRule(RelativeLayout.ALIGN_BOTTOM,
                this.M_nameTextView.getId());
        speedParam.addRule(RelativeLayout.LEFT_OF,
                this.M_activityButton.getId());

        this.M_speedTextView.setText("0 KiB/s");
        this.M_speedTextView.setTextSize(15);

        this.M_layout.addView(this.M_speedTextView, speedParam);

        return this.M_layout;
    }

    TextView M_speedTextView;
    TextView M_nameTextView;
    ProgressBar M_progressBar;
    Button M_activityButton;
    RelativeLayout M_layout;
}

Теперь я создал массив из ListViewItem и хочу добавить эти элементы массива в ListView. (Мы можем получить макет, содержащий все эти представления, используя метод getLayout() класса ListViewItem).

Обратите внимание, что я хочу добавлять эти представления динамически. Не используя обычный способ его заполнения. Может ли кто-нибудь помочь мне, как я могу добраться до этого?

РЕДАКТИРОВАТЬ Обычный способ: объявить xml-файл как listViewItem, раздуть и использовать его подэлементы и вернуть его в методе getView.

EDIT Класс адаптера, который я сейчас использую, и ошибка LogCat:

public class ListViewAdapter extends BaseAdapter {
    private ArrayList<ListViewItem> M_items;

    public ListViewAdapter(ArrayList<ListViewItem> items) {
        this.M_items = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return this.M_items.get(position).getLayout();
    }

    @Override
    public int getCount() {
        return this.M_items.size();
    }

    @Override
    public ListViewItem getItem(int position) {
        return this.M_items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return this.M_items.get(position).getId();
    }
}

Ошибка LogCat:

09-03 03:56:23.359: E/AndroidRuntime(9415): FATAL EXCEPTION: main
09-03 03:56:23.359: E/AndroidRuntime(9415): java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.ListView.measureScrapChild(ListView.java:1189)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1272)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.ListView.onMeasure(ListView.java:1181)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.RelativeLayout.measureChild(RelativeLayout.java:566)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:381)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:531)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.View.measure(View.java:8313)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.ViewRoot.performTraversals(ViewRoot.java:845)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1866)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.os.Looper.loop(Looper.java:130)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at android.app.ActivityThread.main(ActivityThread.java:3687)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at java.lang.reflect.Method.invokeNative(Native Method)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at java.lang.reflect.Method.invoke(Method.java:507)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
09-03 03:56:23.359: E/AndroidRuntime(9415):     at dalvik.system.NativeStart.main(Native Method)

Заранее спасибо :)

02.09.2012

  • создание XML как ItemView, раздувание этого xml в getView и использование подэлементов этого представления. Верните наконец. 03.09.2012
  • Разве вы уже не делаете это динамически? 03.09.2012
  • Нет, я хочу добавить объект ListViewItem в свой список. Я не хочу объявлять какой-либо файл xml. 03.09.2012
  • Вы правильно установили адаптер в ListView? Этот адаптер возвращает ваш ListViewItem или нет? 03.09.2012
  • Моя проблема в том, что! Как я могу добавить возвращенные Layout из объектов класса ListViewItem (используя obj.getLayout()) в ListView? 03.09.2012
  • @auselen: я добавил адаптер, который я использую, и ошибку LogCat. 03.09.2012
  • давайте продолжим это обсуждение в чате 03.09.2012

Ответы:


1

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

https://p-xr.com/android-tutorial-dynamicaly-load-more-items-to-the-listview-never-ending-list/

02.09.2012

2

Обычно ваш адаптер списка использует какую-то структуру данных или контейнер для хранения своих объектов. Если вам нужно добавить новый элемент, сначала добавьте его в контейнер, а затем вызовите

adapter.notifyDataSetChanged();

чтобы сообщить ему, что его данные изменились и должны быть обновлены.

Вот лишь небольшой пример, который направит вас в правильном направлении. Я надеюсь, что вы найдете это полезным.

Определите свою ListActivity:

package com.myapp.listviewexample;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ListViewExampleActivity extends ListActivity {

    static final String[] COUNTRIES = new String[] {
        "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
        "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
        "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan"
      };


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

      //setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));
      final MyListAdapter adapter = new MyListAdapter(this, COUNTRIES);
      setListAdapter(adapter);

      ListView lv = getListView();
      //lv.setTextFilterEnabled(true);

      lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {

            adapter.removeItem(position);
            adapter.notifyDataSetChanged();
          // When clicked, show a toast with the TextView text
          Toast.makeText(getApplicationContext(), ((TextView) view).getText() + " removed",
              Toast.LENGTH_SHORT).show();
        }
      });
    }

}

Определите адаптер списка:

package com.myapp.listviewexample;

import java.util.ArrayList;
import java.util.Arrays;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyListAdapter extends BaseAdapter {

    private ArrayList<String> items;
    private Context mContext;

    public MyListAdapter(Context c, String[] countries) {
        items = new ArrayList<String>(Arrays.asList(countries));
        mContext = c;
        Log.i("MyListAdapter", "countries.length == items.size() " + (countries.length == items.size()));
    }

    public int getCount() {
        return items.size();
    }

    public Object getItem(int position) {
        return items.get(position);
    }

    public long getItemId(int position) { 
        return position;
    }

    public void removeItem(int position) {
        items.remove(position);
    }

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = li.inflate(R.layout.list_item, null);
        } else {
            view = convertView;
        }

        TextView tv = (TextView) view;//.findViewById(R.id.text_view_item);
        tv.setText(items.get(position));

        return view;
    }

}

Рассмотрите возможность использования шаблона ViewHolder для адаптера, чтобы избежать ненужного увеличения представлений. Этот пост может помочь: Как заставить мой ArrayAdapter следовать шаблону ViewHolder?

Определите файл list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="https://schemas.android.com/apk/res/android"
    android:id="@+id/text_view_item"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="16sp" >
</TextView>
03.09.2012
  • Голос +, спасибо. это не мои средства, я разместил ответ, как указано выше :-) 05.09.2012

  • 3

    Попытка использовать этот класс вместо класса ListViewItem, который опубликовал:

    public class ListViewItem extends RelativeLayout {
        @SuppressWarnings("deprecation")
        public ListViewItem(Context context) {
            super(context);
    
            this.M_speedTextView = new TextView(context);
            this.M_nameTextView = new TextView(context);
            this.M_progressBar = new ProgressBar(context, null,
                    android.R.attr.progressBarStyleHorizontal);
            this.M_activityButton = new Button(context);
    
            this.M_speedTextView.setId(new Random().nextInt());
            this.M_nameTextView.setId(new Random().nextInt());
            this.M_progressBar.setId(new Random().nextInt());
            this.M_activityButton.setId(new Random().nextInt());
    
            this.setId(new Random().nextInt());
    
            /***************************************************************/
            this.setLayoutParams(new AbsListView.LayoutParams(
                    LayoutParams.FILL_PARENT, 50));
            this.setBackgroundResource(android.R.color.transparent);
    
            // Name Text setting
            LayoutParams nameTextParams = new LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    
            nameTextParams.setMargins(5, 10, 0, 0);
            nameTextParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 1);
            nameTextParams.addRule(RelativeLayout.LEFT_OF,
                    this.M_speedTextView.getId());
    
            this.M_nameTextView.setTextSize(15);
            this.M_nameTextView.setText("TextView");
            this.M_nameTextView.setSingleLine();
            this.M_nameTextView.setEllipsize(TruncateAt.END);
    
            this.addView(this.M_nameTextView, nameTextParams);
    
            // Activity Button setting
            LayoutParams activityParams = new LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    
            activityParams.setMargins(0, 5, 5, 0);
            activityParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 1);
            activityParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, 1);
    
            this.M_activityButton.setText("Start");
    
            this.addView(this.M_activityButton, activityParams);
    
            // ProgressBar setting
            LayoutParams progressParams = new LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    
            progressParams.addRule(RelativeLayout.ALIGN_BOTTOM,
                    this.M_activityButton.getId());
            progressParams.addRule(RelativeLayout.ALIGN_LEFT,
                    this.M_nameTextView.getId());
            progressParams.addRule(RelativeLayout.BELOW,
                    this.M_nameTextView.getId());
            progressParams.addRule(RelativeLayout.LEFT_OF,
                    this.M_activityButton.getId());
    
            this.addView(this.M_progressBar, progressParams);
    
            // Speed TextView setting
            LayoutParams speedParam = new LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT);
            speedParam.addRule(RelativeLayout.ALIGN_BASELINE,
                    this.M_nameTextView.getId());
            speedParam.addRule(RelativeLayout.ALIGN_BOTTOM,
                    this.M_nameTextView.getId());
            speedParam.addRule(RelativeLayout.LEFT_OF,
                    this.M_activityButton.getId());
    
            this.M_speedTextView.setText("0 KiB/s");
            this.M_speedTextView.setTextSize(15);
    
            this.addView(this.M_speedTextView, speedParam);
        }
    
        public void setSpeed(int speed) {
            this.M_speedTextView.setText(Integer.toString(speed));
        }
    
        public void setName(String name) {
            this.M_nameTextView.setText(name);
        }
    
        public void setProgress(int progress) {
            this.M_progressBar.setProgress(progress);
        }
    
        public void setButtonText(String text) {
            this.M_activityButton.setText(text);
        }
    
        TextView M_speedTextView;
        TextView M_nameTextView;
        ProgressBar M_progressBar;
        Button M_activityButton;
    }
    

    и в getView методе адаптера:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return this.M_items.get(position);
    }
    
    03.09.2012
    Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]