2011-12-30 3 views
7

У меня есть приложение, которое извлекает объявления, хранящиеся в виде XML-файлов на сервере, и загружает заголовок и автора каждого объявления в элемент ListView. То, что мне также нужно хранить с каждым элементом, - это идентификатор каждого объявления, но мне фактически не нужно его отображать. Я подумал о том, чтобы сохранить идентификатор в хэш-карте, которую я использую, чтобы заполнить список, а затем найти связанный идентификатор с нажатым названием, но я думаю, что было бы небезопасно использовать, поскольку два объявления могут иметь один и тот же заголовок (и автора и дату) , Я также думал о добавлении невидимого TextView к каждому элементу для хранения идентификатора, но это вызывало проблемы с макетом. Наконец, я обыскал и нашел setTag() и getTag(), которые, я думаю, были бы идеальны для того, что я хочу сделать, но я не уверен, как их использовать с SimpleAdapter (я относительно новичок в этом ...). Если идея TextView это то, что мне нужно сделать (хотя я сомневаюсь), вот макет Я использую для каждого элемента:Прикрепление идентификационных данных к элементам списка просмотра

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@android:id/text1" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="6dip" 
     android:textAppearance="?android:attr/textAppearanceMedium"/> 
    <LinearLayout 
     android:orientation="horizontal" 
     android:id="@+id/items" 
     android:weightSum="100" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 
     <TextView 
      android:id="@android:id/text2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="6dip" 
      android:textAppearance="?android:attr/textAppearanceSmall" 
      android:layout_weight="85"/> 
     <LinearLayout 
      android:orientation="vertical" 
      android:id="@+id/itemCB" 
      android:layout_weight="15" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:gravity="center"> 
      <CheckBox 
       android:id="@+id/cbSelected" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" /> 
     </LinearLayout> 
    </LinearLayout> 
</LinearLayout> 

И я использую следующий адаптер для заполнения списка:

for(int i = 0; i < ann.length; i++) 
{ 
    map = new HashMap<String, String>(); 
    map.put("line1", ann[i].getTitle()); 
    map.put("line2", "Posted by: " + ann[i].getAuthor() + "\n" + ann[i].date.toLongString()); 
    list.add(map); 
} 
String[] from = { "line1", "line2"}; 

int[] to = { android.R.id.text1, android.R.id.text2}; 

SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.twoline_checkbox_id_listitem, from, to); 
setListAdapter(adapter); 

Благодарим за помощь!

+0

Я думаю, что здесь лучший ответ для вас: http://stackoverflow.com/a/3051729/7379190 – AleX

+0

Я думаю, что [это] (HTTP : //stackoverflow.com/a/3051729/7379190) - лучший ответ на ваш вопрос. – AleX

ответ

3

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

Существует множество примеров, которые могут показать вам, как расширить ArrayAdapter. Самая важная часть, однако, является getView() метод, который в это самая основная форма может выглядеть примерно так:

public View getView(int position, View convertView, ViewGroup parent) { 
    View row; 
    if (null == convertView) { 
     row = mInflater.inflate(R.layout.list_item, null); 
    } else { 
     row = convertView; 
    } 

    MyObject item = (MyObject) getItem(position); 

    TextView tv = (TextView) row.findViewById(android.R.id.xxx); 
    tv.setText(item.getTitle); 

    // same for other fields/views; e.g. author, date etc 

    return row; 
} 

Вместо создания SimpleAdapter, теперь создать экземпляр вашего CustomAdapter, передать ему свой массив (или список) объектов сущностей, и установить всю как адаптер к вашему списку:

MyObject[] objects = ... 
setListAdapter(new ArrayAdapter<string>(this, R.layout.list_item, objects)); 

Поскольку вы теперь имеете дело с объектами непосредственно, вместо первого создания кучи представления строк из разных областей, вы также можете легко получить доступ к «идентификатору» каждого элемента. Еще лучше, вы можете добавить много разных полей, не беспокоясь о том, как это будет выглядеть в списке, поскольку визуальное представление определяется тем, что вы установили (и не устанавливаете) в методе getView() вашего адаптера.

+0

Да, я боялся, что мне, возможно, придется вникать в создание моего собственного адаптера. Это, вероятно, кое-что, что мне нужно узнать, хотя, спасибо за помощь! О, и массив 'ann' представляет собой массив объектов объявления, созданных с использованием простого XML-парсера, просто fyi. :) – lancex

+0

Я понимаю, что это может быть немного препятствие, которое нужно предпринять в первый раз, но как только вы это выясните, я убежден, что вы согласитесь, что это стоило усилий. Не стоит беспокоиться, если вы застряли на полпути, всегда есть люди, находящиеся на SO, чтобы помочь. :) –

4

Я просто хочу объяснить более подробно ответ MH.
В вашей myArrayAdapter класс в getView функции можно назначить свой идентификатор в View (который на самом деле означает «строка»), как это:

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

    View v = convertView; 

    if (v == null) { 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(mItemLayout, null); 
    } 

    String[] dataForOneRow = this.allRowsData.get(position); 

    // Tag is expected to be an Object (Integer is an object) 
    // our data are in String array - that's why we need to convert it into Integer 
    // I assume here, your ID number is first item (No.0) in the array of data 
    v.setTag(new Integer(Integer.valueOf(dataForOneRow[0]))); 

    /* 
    ...here you will set your data to display in your TextViews... 
    */ 

    return v; 
} 

И тогда вы должны знать идентификатор подряд, когда (например,) пользователь щелкнул по строке, и начнется некоторое подробное действие.

У меня есть мой ListView в Fragment и это кусок кода из моего главного Activity, из декларации Fragment, помещенную в функции onCreateView:

// here we assign "onClick listener" when user clicks a row 
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 

    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     Intent myRowClickIntent = new Intent(getActivity(), myDetailActivity.class); 
     // we can send some data to the new Activity through "extras" 
     // remember - our Tag is an object (Integer object) but putExtra() awaits some integer or string or some other type 
     // so here we are saying that it should be understood/treated as an Integer 
     myRowClickIntent.putExtra("item_id", (Integer)view.getTag()); 
     startActivity(myRowClickIntent); 
    } 
}); 

И, наконец, вот кусок кода из onCreate метод моего DetailActivity:

Bundle myExtras; 
int myItemId; 

myExtras = getIntent().getExtras(); 
if (myExtras != null) { 
    myItemId = myExtras.getInteger("item_id"); 
} 

Надеется, что это помогает кому-то ... :)
Я также новый для Android.
Большого thank you в StackOverflow для такой помощи в обучении Android развития :)

Смежные вопросы