2013-05-28 4 views
1

Я показываю данные в списке из json, используя AsynTask.«Separator» в listview

Код указан здесь.

public class MenuTask extends AsyncTask<String, String, String> { 

    @Override 
    protected String doInBackground(String... arg0) { 
     // TODO Auto-generated method stub 
     List<NameValuePair> params = new ArrayList<NameValuePair>(); 
     // Getting JSON String from URL.............. 
     JSONObject jsonObject = jParser.makeHttpRequest(
       "http://smartaway.dk/json/submenu.php?resid=" + res_id, 
       "POST", params); 
     try { 
      bestdeal = jsonObject.getJSONArray(TAG_MENU); 

      ///LOOping through AllEvents........ 
      for (int i = 0; i < bestdeal.length(); i++) { 
       JSONObject e = bestdeal.getJSONObject(i); 
       String resname = e.getString(TAG_MENUNAME); 
       String city_state = e.getString(TAG_PRICE); 

       // Creating New HAsh Map......... 
       HashMap<String, String> map = new HashMap<String, String>(); 
       // adding each child node to HashMap key => value 
       // map.put(TAG_ID, id); 
       map.put(TAG_MENUNAME, resname); 
       map.put(TAG_PRICE, city_state); 
       /* 
       * map.put(TAG_STREET, street); map.put(TAG_COUSINE, 
       * cousine); map.put(TAG_RES_LOGO, reslogo); 
       */ 
       // adding HashList to ArrayList 
       bestdeal_list.add(map); 
      } 
      // } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @SuppressWarnings("deprecation") 
    @Override 
    protected void onPostExecute(String result) { 

     super.onPostExecute(result); 

     /* 
     * if(bestdeal_list.isEmpty()){ AlertDialog alertDialog=new 
     * AlertDialog.Builder(getParent()).create(); 
     * alertDialog.setTitle("No Best Deal Found"); 
     * alertDialog.setButton("Ok", new DialogInterface.OnClickListener() 
     * { 
     * 
     * @Override public void onClick(DialogInterface dialog, int which) 
     * { 
     * 
     * 
     * } }); alertDialog.show(); } else{ 
     */ 
     /* 
     * if (bestdeal_list.isEmpty()) { 
     * Toast.makeText(getApplicationContext(), "Empty Menu", 
     * Toast.LENGTH_LONG).show(); } else{ 
     */ 
     runOnUiThread(new Runnable() { 
      public void run() { 
       /** 
       * Updating parsed JSON data into ListView 
       * */ 
       ListAdapter adapter = new SimpleAdapter(
         RestaurantDetails.this, bestdeal_list, 
         R.layout.menu_list, new String[] { TAG_MENUNAME, 
           TAG_PRICE }, new int[] { R.id.textView1, 
           R.id.textView3 }); 
       list.setAdapter(adapter); 

      } 
     }); 
    } 
    // } 
} 

Все работает нормально, но я хочу изменить свой код, разделив список на разделы. Я хочу, чтобы первые 4 элемента списка под категорией 1 находились в других 4 элементах списка под категорией 2. Я не хочу расширения списка. Просто хочу изменить вышеупомянутый код.

+0

Вы можете сделать это, реализовав свой пользовательский адаптер. http://stackoverflow.com/a/1606642/2410326 – ooops

+0

http://stackoverflow.com/questions/2394514/how-to-generate-a-listview-with-headers-above-some-sections –

ответ

2
  1. onPostExecute вызывается на главном («UI») потоке, так что на самом деле нет необходимости запускать свой код через runOnUiThread(Runnable).
  2. Если вы хотите отобразить два типа представлений в том же ListView вам нужно будет изменить свой Adapter, чтобы поставить его (см Adapter.getViewTypeCount()), то вам нужно будет сортировать набор данных (List в вашем примере), так что он будет отражать ваши запрошенные разделы сортировки +, и, наконец, вам нужно будет обработать их в своем адаптере (верните соответствующий тип/представление по данной позиции). Также см. Adapter.getItemViewType() и Adapter.getView().
+0

Могу ли я получить это после изменения моего выше кода в post execute. –

+0

a. 'postExecute()' thingy действительно не связано с вашей основной проблемой b. вы можете добавлять разделы связанные объекты в свой «Список» (например, добавлять (TitleA), добавлять (DataA1), добавлять (DataA2) ..., добавлять (TitleB), добавлять (DataB1), добавлять (DataB2) ... -> просто один из многих способов дифференцировать внутренние типы набора данных адаптера) – avimak

1

Есть несколько вариантов выбора. Посмотрите ссылку в одном из комментариев на свой вопрос или посмотрите на SectionedAdapter, который я написал некоторое время назад.

Что вы в основном хотите сделать, это использовать пользовательский адаптер, скорее всего, полученный из BaseAdapter. Вам нужно будет переопределить getViewTypeCount() и вернуть количество различных элементов списка, которые у вас есть в списке. В вашем случае это 2, поскольку у вас есть обычные элементы и категории списка.

Вам также необходимо переопределить getItemViewType(position) и вернуть либо 0, если элемент в указанной позиции является обычным элементом списка или 1, если это категория.

Наконец, вам также придется переопределить getView() и вернуть элемент списка соответствующего типа (категории или элемента обычного списка) на основе getItemViewType().

1

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

Сначала указать расположение элемента списка, как это:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" android:layout_height="wrap_content" > 

    <TextView 
     android:id="@+id/section_header" 
     android:layout_width="match_parent" android:layout_height="wrap_content" /> 

    <RelativeLayout 
     android:layout_below="@id/section_header" 
     android:layout_width="match_parent" android:layout_height="wrap_content"> 

     <!-- your layout here ... --> 

    </RelativeLayout> 

</RelativeLayout> 

Затем, в вашем адаптере, решить, если вы хотите, чтобы показать заголовок раздела или нет.

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View view = super.getView(position, convertView, parent); 
    bindSectionHeader(position, view); 
    return view; 
} 

private void bindSectionHeader(int position, View view) { 
    TextView sectionView = (TextView) view.findViewById(R.id.section_header); 

    if (isBeginningOfSection(position)) { 
     sectionView.setText(getSectionTitle(position)); 
     sectionView.setVisibility(View.VISIBLE); 
    } else { 
     sectionView.setVisibility(View.GONE); 
    } 
} 

private boolean isBeginningOfSection(int position) { 
    // ... 
} 

private String getSectionTitle(int position) { 
    // ... 
} 

AlphabetIndexer может помочь с внедрением двух методов.