Переопределить или добавить одну строку в пользовательском ListView

Я работаю над списком меню для приложения, которое я делаю. Я следовал этому руководству по его созданию (изменив значения по мере необходимости) - http://www.ezzylearning.com/tutorial.aspx?tid=1763429.

Теперь мой список не супер сложный. У него будут одни и те же данные каждый раз, и будет только два раздела. Пока мой список работает, но мне нужно заменить 7-й элемент другим представлением/макетом в xml или добавить это представление.

Текущий код....

Основная деятельность:

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;


public class HU_main extends Activity {

    private ListView f_menu;

        @Override
        public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.hu_main);

        Front_menu front_menu_data[] = new Front_menu[] {
            new Front_menu("Cadences", "Reference chart of all the primary cadences."),
            new Front_menu("Chords and Non-Chord Tones", "Reference chart of chord types and non-chord tones and associated rules of NCTs."),
            new Front_menu("Key Signatures", "Reference chart for key signature rules."),
            new Front_menu("Scale/Mode Triads", "List of triads and degrees for all standard diatonic scale modes."),
            new Front_menu("Harmonic Progression", "Reference chart for scale and mode chord progressions."),
            new Front_menu("Terminology Translation", "Reference list if primary music terms and instruments in German, Italian and French."),
            new Front_menu("Replace", "Replace"),
            new Front_menu("Chord Finder", "Enter notes to find chords."),
            new Front_menu("Modulation", "Reference chart of chord types and non-chord tones and associated rules of NCTs."),
            new Front_menu("Scale Finder", "Find scales and modes by notes."),
            new Front_menu("Transposition", "Show changes to and from concert pitch for transposing instruments or determine overall transposition of key.")
            };

            Front_menuAdapter adapter = new Front_menuAdapter(this,
            R.layout.item_layout, front_menu_data);

            f_menu = (ListView)findViewById(R.id.f_menu);

            f_menu.setAdapter(adapter);


        }

    }

Front_menuАдаптер:

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;


public class Front_menuAdapter extends ArrayAdapter<Front_menu> {
    Context context;
    int layoutResourceId;
    Front_menu data[] = null;



    public Front_menuAdapter(Context context, int layoutResourceId, Front_menu[] data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    Front_menuHolder holder = null;


        if (row == null) {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new Front_menuHolder();
            holder.txtTitle1 = (TextView)row.findViewById(R.id.menu_item);
            holder.txtTitle2 = (TextView)row.findViewById(R.id.item_description);
            holder.header2 = (TextView)row.findViewById(R.id.tools_header);

            row.setTag(holder);


            if (position != 6) {
                holder.txtTitle1.setVisibility(View.VISIBLE);
                holder.txtTitle2.setVisibility(View.VISIBLE);
                holder.header2.setVisibility(View.GONE);
            }

            else if (position == 6) {
                holder.header2.setVisibility(View.VISIBLE);
                holder.txtTitle1.setVisibility(View.GONE);
                holder.txtTitle2.setVisibility(View.GONE);
            }

        }

        else {
            holder = (Front_menuHolder)row.getTag();
        }


        Front_menu front_menu = data[position];
        holder.txtTitle1.setText(front_menu.item);
        holder.txtTitle2.setText(front_menu.desc);

        return row;
    }

    class Front_menuHolder {
        TextView txtTitle1;
        TextView txtTitle2;
        TextView header2;
    }

}


Front_menu (constructor):

    public class Front_menu {
        public String item;
        public String desc;
        public Front_menu() {
             super();
        }

        public Front_menu(String item, String desc) {
            super();
            this.item = item;
            this.desc = desc;
        }

    }

person anathematized_one    schedule 22.04.2013    source источник


Ответы (1)


Вместо того, чтобы беспокоиться о раздувании нового View для того, чтобы один элемент отображался по-другому, почему бы просто не определить еще один layout в текущем XML?

Возьмем, к примеру, реальный фрагмент кода из моего приложения, которое показывает новостную ленту пользователя Facebook (я сократил его и удалил из него ненужный код). Пользователь может иметь обновление статуса / фото или видео в своей ленте новостей. Поэтому вместо создания нескольких XML-файлов макета я определяю их все в одном XML-коде, который я расширяю в файле adapter.

Пример XML:

    <!-- STATUS | PHOTO -->

    <LinearLayout
        android:id="@+id/linlaStatusPhoto"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp"
        android:gravity="center"
        android:orientation="vertical"
        android:visibility="gone" >

        .... OTHER ELEMENTS NEEDED

    </LinearLayout>


    <!-- VIDEO LAYOUT -->

    <LinearLayout
        android:id="@+id/linlaVideo"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:visibility="gone" >

        .... OTHER ELEMENTS NEEDED

    </LinearLayout>

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

if (feedType.equals("status") || feedType.equals("photo"))  {

    // SHOW THE NECESSARY LAYOUT CONTAINER
    holder.linlaStatusPhoto.setVisibility(View.VISIBLE);

    // HIDE THE OTHERS
    holder.linlaVideo.setVisibility(View.GONE);

  // I HAVE MORE CONDITIONS TO CHECK. HENCE THE else if().
} else if (feedType.equals("video")) {

    // SHOW THE NECESSARY LAYOUT CONTAINER
    holder.linlaVideo.setVisibility(View.VISIBLE);

    // HIDE THE OTHERS
    holder.linlaStatusPhoto.setVisibility(View.GONE);

}

Вы можете легко адаптировать этот код, чтобы он соответствовал вашей схеме вещей. Вам нужно будет использовать некоторую проверку, чтобы определить, какие Widget должны отображаться. Но это верно, даже если бы вы надули еще один View. Если это всегда 7-й элемент в списке, вы можете добавить еще один параметр к вашему front_menu_data[], который будет содержать номер элемента, и использовать его для запуска приведенного выше примера.

ОБНОВИТЬ:

Переместите блок кода if...else отсюда:

if (row == null) {
    LayoutInflater inflater = ((Activity)context).getLayoutInflater();
    row = inflater.inflate(layoutResourceId, parent, false);

    holder = new Front_menuHolder();
    holder.txtTitle1 = (TextView)row.findViewById(R.id.menu_item);
    holder.txtTitle2 = (TextView)row.findViewById(R.id.item_description);
    holder.header2 = (TextView)row.findViewById(R.id.tools_header);

    row.setTag(holder);

    // MOVE THIS BLOCK
    if (position != 6) {
        holder.txtTitle1.setVisibility(View.VISIBLE);
        holder.txtTitle2.setVisibility(View.VISIBLE);
        holder.header2.setVisibility(View.GONE);
    } else if (position == 6) {
        holder.header2.setVisibility(View.VISIBLE);
        holder.txtTitle1.setVisibility(View.GONE);
        holder.txtTitle2.setVisibility(View.GONE);
    }

} else {
    holder = (Front_menuHolder)row.getTag();
}

To:

Front_menu front_menu = data[position];

if (position != 6) {
    holder.txtTitle1.setVisibility(View.VISIBLE);
    holder.txtTitle2.setVisibility(View.VISIBLE);
    holder.header2.setVisibility(View.GONE);

    holder.txtTitle1.setText(front_menu.item);
    holder.txtTitle2.setText(front_menu.desc);

} else if (position == 6) {
    holder.header2.setVisibility(View.VISIBLE);
    holder.txtTitle1.setVisibility(View.GONE);
    holder.txtTitle2.setVisibility(View.GONE);

    holder.txtTitle1.setText(front_menu.item);
    holder.txtTitle2.setText(front_menu.desc);
}
person Siddharth Lele    schedule 22.04.2013
comment
Спасибо, я попробую это. Где именно в моем адаптере выше я могу добавить Java? - person anathematized_one; 23.04.2013
comment
На самом деле не волнуйтесь, я понял, куда его поместить, и он работает. Большое спасибо, я боялся, что мне придется влить невероятное количество кода, чтобы получить только одно представление. Мне нужно только немного настроить его, чтобы удалить для этого возможность рисования, и он работает именно так, как я хотел. - person anathematized_one; 23.04.2013
comment
@anathematized_one: Я рад, что ты это понял. :-) - person Siddharth Lele; 23.04.2013
comment
может я не совсем правильно выразился. Это работает, и я исправил свой макет, но когда я прокручиваю список вниз и снова прокручиваю вверх, довольно много раз он перемещает новое представление в неправильное место. Где он у меня сейчас находится под if (row == null) { и после row.setTag(holder); а у меня как будто (position != 6) { и какие виды показывать и else if (position == 6) { и какие виды показывать... - person anathematized_one; 23.04.2013
comment
@anathematized_one: Можете ли вы обновить ОП новым кодом? Посмотрим, что можно с этим сделать. :-) - person Siddharth Lele; 23.04.2013
comment
Обновлено. Спасибо за помощь... если бы у меня была такая репутация, я бы поставил тебя на хардкор. О, кроме того, мне пришлось изменить элемент, который был изменен (теперь это 6 из-за раздутого представления заголовка, о котором я забыл). Кроме того, когда я впервые запускаю действие, оно работает нормально, только после прокрутки оно работает там, где должно быть новое представление. - person anathematized_one; 24.04.2013
comment
@anathematized_one: Проверьте обновление и посмотрите, исправит ли оно это. - person Siddharth Lele; 24.04.2013
comment
ФАНТАСТИКА! Это прибило это, спасибо. Теперь, когда я думаю об этом (используя компьютер, а не линейную логику), это имеет гораздо больше смысла. Работает безупречно. - person anathematized_one; 24.04.2013
comment
@anathematized_one: Это случается с лучшими из нас, когда нас хоронят в коде. ;-) Я рад, что смог помочь. :-) - person Siddharth Lele; 24.04.2013