2015-09-29 21 views
0

目前我正在使用Android應用程序,並使用解析作爲後端,我已經動態地創建了附近地點的ListView。但我面臨以下設計問題:當用戶點擊某個地點時,必須在所點擊的項目下方出現一個視圖。Android上的動態ListView問題

我在分組這個地方遇到了問題,如圖1所示,匯豐銀行有很多分行。在這種情況下,他們在匯豐銀行。

我已經試過可擴展的ListView之前,但它沒有給子視圖,只是簡單的一個定製。

我BaseAdapter:

import java.util.ArrayList; 
import java.util.List; 

import com.parse.ParseGeoPoint; 

import android.content.Context; 
import android.content.Intent; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.view.ViewManager; 
import android.widget.BaseAdapter; 
import android.widget.ImageView; 
import android.widget.TextView; 
import android.widget.Toast; 

public class ListViewAdapter extends BaseAdapter { 

    // Declare Variables 
    Context context; 
    LayoutInflater inflater; 
    //ImageLoader imageLoader; 
    private List<AnywallPost> AnywallPostlist = null; 
    private ArrayList<AnywallPost> arraylist; 

    public ListViewAdapter(Context context, 
      List<AnywallPost> AnywallPostlist) { 
     this.context = context; 
     this.AnywallPostlist = AnywallPostlist; 
     inflater = LayoutInflater.from(context); 
     this.arraylist = new ArrayList<AnywallPost>(); 
     this.arraylist.addAll(AnywallPostlist); 

    } 

    public class ViewHolder { 
     TextView distance; 
     TextView name; 

    } 

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

    @Override 
    public Object getItem(int position) { 
     return AnywallPostlist.get(position); 
    } 

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

    public View getView(final int position, View view, ViewGroup parent) { 
     final ViewHolder holder; 
     final View row=view; 

     if (view == null) { 
      holder = new ViewHolder(); 
      view = inflater.inflate(R.layout.user_custom, null); 
      // Locate the TextViews in listview_item.xml 
      holder.distance = (TextView) view.findViewById(R.id.disView); 
      holder.name = (TextView) view.findViewById(R.id.nameView); 


      view.setTag(holder); 
     } else { 
      holder = (ViewHolder) view.getTag(); 
     } 
     // Set the results into TextViews 

     holder.name.setText(AnywallPostlist.get(position).getText()); 
     holder.distance.setText(AnywallPostlist.get(position).getDis()); 


     //Listen for ListView Item Click 
     view.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 

       Toast.makeText(context,AnywallPostlist.get(position).getText(), Toast.LENGTH_LONG).show(); 


      } 
     }); 
     return view; 
    } 

} 

switch (getItemViewType(position)) { 
      case 0: 
       Bank bank = (Bank) getItem(position); 
       holder.name.setText(bank.name); 
       String str = String.valueOf(bank.numBranches); 
       holder.cn.setText(str); 
       imageLoader.DisplayImage(bank.image, 
         holder.logo); 
       Toast.makeText(getActivity(), "img"+bank.image,Toast.LENGTH_LONG).show(); 
       // ... set the image here 
       // ... set the number of branches here 
       break; 
      case 1: 
       branch = (AnywallPost) getItem(position); 
       holder.name.setText(branch.getText()); 
       holder.distance.setText(branch.getDis()); 
       holder.b.setText(branch.getbranch()); 
       imageLoader.DisplayImage(branch.getimg(), 
         holder.logo); 
       break; 
      case 2: 
       branch = (AnywallPost) getItem(position); 
       holder.name.setText(branch.getText()); 
       holder.distance.setText(branch.getDis()); 
       holder.b.setText(branch.getbranch()); 
       imageLoader.DisplayImage(branch.getimg(), 
         holder.logo); 
       // ... set values for all the expanded view widgets too 
       break; 
     } 

我已經使用這個代碼來解析得到形象,我把它添加到AnywallPost

ParseFile image = (ParseFile) country.get("image"); 

AnywallPost map = new AnywallPost(); 

map.setimg(image.getUrl()); 

然後,我用這個代碼加載圖像,它能正常工作

imageLoader.DisplayImage(AnywallPostlist.get(position).getimg(), 
       holder.logo); 
+0

你熟悉如何'Adapter'方法'getViewTypeCount()'和'getItemViewType()'工作嗎? –

+0

@ krislarson是的,我願意。你可以幫我嗎 ? – Mariam

+0

我有一個想法,我現在很忙,但我會在一個小時內發佈答案 –

回答

0

這是我的想法:

你將有兩種佈局,一個簡短的名字& distan ce和一個擴展名爲&的距離加上所有的細節。

簡要的佈局將有0視圖類型,當你點擊項目展開佈局將有1

視圖類型,在列表模式設置一個標誌,表明視圖已從簡短視圖切換到長視圖。所以你應該看到視圖開關。如果您點擊擴展視圖,它將恢復爲簡要視圖。

我沒有辦法來測試這一點,但這裏是我怎麼想的代碼看起來:

public class ListViewAdapter extends BaseAdapter { 

    // Declare Variables 
    Context context; 
    LayoutInflater inflater; 
    //ImageLoader imageLoader; 
    private List<AnywallPost> AnywallPostlist = null; 
    private ArrayList<AnywallPost> arraylist; 

    /** this array holds a flag for each item to show if it is in brief view more or expanded view mode*/ 
    private boolean[] expandedView; 

    public ListViewAdapter(Context context, 
      List<AnywallPost> AnywallPostlist) { 
     this.context = context; 
     this.AnywallPostlist = AnywallPostlist; 
     inflater = LayoutInflater.from(context); 
     this.arraylist = new ArrayList<AnywallPost>(); 
     this.arraylist.addAll(AnywallPostlist); 

     this.expandedView = new boolean[AnywallPostlist.size()]; 
    } 

    public class ViewHolder { 
     TextView distance; 
     TextView name; 
     // ... add all your expanded view fields here too 
    } 

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

    @Override 
    public int getViewTypeCount() { 
     return 2; // brief & expanded 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return expandedView[position] ? 1 : 0; 
    } 

    @Override 
    public Object getItem(int position) { 
     return AnywallPostlist.get(position); 
    } 

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

    public View getView(final int position, View view, ViewGroup parent) { 
     final ViewHolder holder; 
     final View row=view; 

     if (view == null) { 
      holder = new ViewHolder(); 
      int layout = expandedView[position] ? R.layout.user_custom_expanded : R.layout.user_custom; 
      view = inflater.inflate(layout, parent, false); 
      // Locate the TextViews in listview_item.xml 
      holder.distance = (TextView) view.findViewById(R.id.disView); 
      holder.name = (TextView) view.findViewById(R.id.nameView); 

      if (expandedView[position]) { 
       // ... locate all the expanded view widgets too 
      } 

      view.setTag(holder); 
     } else { 
      // because the view type is determined by expandedView[position], the correct layout will be recycled here 
      holder = (ViewHolder) view.getTag(); 
     } 
     // Set the results into TextViews 

     holder.name.setText(AnywallPostlist.get(position).getText()); 
     holder.distance.setText(AnywallPostlist.get(position).getDis()); 

     if (expandedView[position]) { 
      // ... set all the values for your expanded view too 
     } 

     //Listen for ListView Item Click 
     view.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 

       if (expandedView[position]) { 
        // this is expanded view so toggle it back to brief view 
        expandedView[position] = false; 
       } else { 
        // clear any expanded views elsewhere 
        expandedView = new boolean[AnywallPostlist.size()]; 
        // toggle brief view to expanded 
        expandedView[position] = true; 
       } 

       // forces the ListView to refresh and convert the brief view into an expanded view and vice versa. 
       ListViewAdapter.this.notifyDataSetChanged(); 
       // Toast.makeText(context,AnywallPostlist.get(position).getText(), Toast.LENGTH_LONG).show(); 
      } 
     }); 

     if (expandedView[position]) { 
      // ... add all your event listeners for the expanded view widgets 
     } 

     return view; 
    } 

} 

您還可以添加與展開/摺疊指示器視圖,以控制切換按鈕展開/摺疊,所以你不要點擊視圖上的任何地方來改變它。

如果你願意,你可以用ExpandableListView做到這一點,你只需要改變爲ExpandableListAdapter並且你的佈局有一些不同。

+0

非常感謝你的工作。但我有疑問,如圖1所示,所有分行,例如匯豐銀行將彙集在一起​​。是否有可能在android中做到這一點?以及如何做到這一點?! – Mariam

+0

我在猜測你的代碼片段的頂部有一個TextView,並且AnywallPosts是在銀行名稱的TextView下進入ListView的分支的所有位置。那是你有什麼?現在你有一個_homogenous_列表(每個項目都是AnywallPost)。您還可以將所有銀行和位置混合在一個列表中(_heterogenous_)。這個邏輯稍微複雜一些,但非常可行。 ListView只是問一個適配器,「什麼位置_n_?」你可以告訴它任何你想要的。 –

+0

讓我解釋一下這個設計,這個設計是針對IOS的,我嘗試使它成爲android,所以我製作了具有許多片段的滑塊菜單,比如:bank,teleccom等等。當用戶點擊銀行時,應顯示存儲在解析中的附近地點。第一行:銀行名稱。第二行:銀行分行,當點擊分行時,應爲用戶顯示詳細信息。如果同一家銀行有很多分行,則應該全部歸屬該銀行。 – Mariam

0

下面是一些代碼,以使異構列表:

在構造函數取一個很好看,看我如何通過銀行他們串成他們都連成一個大名單瓜分了分支機構。

名單只是一個Object陣列,所以你找出項目是什麼樣的:

如果它是一個Bank,那麼好,這是一個銀行。

如果它是一個AnywallPostexpandedView[position] == false那麼它的一個分支,簡短視圖

如果它是一個AnywallPostexpandedView[position] == true那麼它的一個分支,擴展視圖

public class Bank { 
    private String name; 
    private String image; // maybe this needs to be URL? 
    private int numBranches; 
} 

public class ListViewAdapter extends BaseAdapter { 

    // Declare Variables 
    Context context; 
    LayoutInflater inflater; 
    ImageLoader imageLoader; 
    private Object[] masterList; 

    /** this array holds a flag for each item to show if it is in brief view more or expanded view mode*/ 
    private boolean[] expandedView; 

    public ListViewAdapter(Context context, 
          List<AnywallPost> AnywallPostlist) { 
     this.context = context; 
     inflater = LayoutInflater.from(context); 

     /* 
     * Phase I -- get list of banks and organize the branches by bank 
     */ 
     int count = 0; 
     List<String bankNames = new ArrayList<String>(); 
     List<Bank> banks = new ArrayList<Bank>(); 
     Map<String, Bank> bankMap = new HashMap<String, Bank>(); 
     Map<String, List<AnywallPost>> mappedBranches = new HashMap<String, List<AnywallPost>>(); 

     Bank bank = null; 
     List<AnywallPost> branches = null; 

     for (AnywallPost branch : AnywallPostlist) { 

      // have we started a branch list for this bank? 
      if (! bankNames.contains(branch.getBank())) { // no we haven't 

       // remember the bank name 
       bankNames.add(branch.getBank()); 

       // init a new Bank 
       bank = new Bank(); 
       bank.name = branch.getBank(); 
       bank.image = branch.getImg(); // if this is URL make image in Bank a URL 
       banks.add(bank); 
       bankMap.put(bank.name, bank); 
       count++; 

       // create a list for this bank's branches and index it by bank 
       branches = new ArrayList<AnywallPost>(); 
       mappedBranches.put(branch.getBank(), branches); 

      } else { // yes we have 

       // get the bank for this name 
       // this fixes the problem with the branch counts 
       bank = bankMap.get(branch.getBank()); 

       // get the branch list we already created for this bank 
       branches = mappedBranches.get(branch.getBank()); 
      } 

      // remember the branch for this bank 
      branches.add(branch); 
      count++; 

      // increment the number of branches for this bank 
      bank.numBranches++; 
     } 

     /* 
     * Phase II -- sort the banks and branches 
     */ 

     // ... here you can order the banks by name, branches by distance, etc. 

     /* 
     * Phase III -- create the mixed list 
     */ 
     int index = 0; 
     masterList = new Object[count]; 

     for (Bank bank : banks) { 

      // append a bank to the list 
      masterList[index] = bank; 
      index++; 

      for (AnywallPost branch : mappedBranches.get(bank.name)) { 

       // append a branch to the list 
       masterList[index] = branch; 
       index++; 
      } 
     } 

     this.expandedView = new boolean[count]; 
    } 

    public class ViewHolder { 
     TextView distance; 
     TextView name; 
     ImageView logo; 
     // ... add all your expanded view fields here too 
    } 

    @Override 
    public int getCount() { 
     return masterList.length; 
    } 

    @Override 
    public int getViewTypeCount() { 
     return 4; // bank brief, bank expanded, branch brief & branch expanded 
    } 

    @Override 
    public Object getItem(int position) { 
     return masterList[position]; 
    } 

    @Override 
    public int getItemViewType(int position) { 
     if (getItem(position) instanceof Bank) { 
      return expandedView[position] ? 1 : 0; 
     } 
     return expandedView[position] ? 3 : 2; 
    } 

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

    @Override 
    public View getView(final int position, View view, ViewGroup parent) { 
     final ViewHolder holder; 
     final View row=view; 

     if (view == null) { 
      holder = new ViewHolder(); 
      int layout = 0; 
      switch (getItemViewType(position)) { 
       case 0: 
        layout = R.layout.bank_brief; 
        break; 
       case 1: 
        layout = R.layout.bank_expanded; 
        break; 
       case 2: 
        layout = R.layout.branch_brief; 
        break; 
       case 3: 
        layout = R.layout.branch_expanded; 
        break; 
      } 
      view = inflater.inflate(layout, parent, false); 

      switch (getItemViewType(position)) { 
       case 0: 
        holder.name = (TextView) view.findViewById(R.id.nameView); 
        break; 
       case 1: 
        holder.name = (TextView) view.findViewById(R.id.nameView); 
        // ... locate all the bank expanded view widgets too 
        break; 
       case 2: 
        holder.name = (TextView) view.findViewById(R.id.nameView); 
        holder.distance = (TextView) view.findViewById(R.id.disView); 
        break; 
       case 3: 
        holder.name = (TextView) view.findViewById(R.id.nameView); 
        holder.distance = (TextView) view.findViewById(R.id.disView); 
        // ... locate all the expanded view widgets too 
        break; 
      } 

      view.setTag(holder); 

     } else { 
      // because the view type is determined by expandedView[position], the correct layout will be recycled here 
      holder = (ViewHolder) view.getTag(); 
     } 

     AnywallPost branch = null; 
     switch (getItemViewType(position)) { 
      case 0: 
       Bank bank = (Bank) getItem(position); 
       holder.name.setText(bank.name); 
       imageLoader.DisplayImage(bank.image, holder.logo); 
       // ... set the number of branches here 
       break; 
      case 1: 
       holder.name.setText(bank.name); 
       imageLoader.DisplayImage(bank.image, holder.logo); 
       // ... set the number of branches here 
       break; 
      case 1: 
       branch = (AnywallPost) getItem(position); 
       holder.name.setText(branch.getText()); 
       holder.distance.setText(branch.getDis()); 
       break; 
      case 2: 
       branch = (AnywallPost) getItem(position); 
       holder.name.setText(branch.getText()); 
       holder.distance.setText(branch.getDis()); 
       // ... set values for all the expanded view widgets too 
       break; 
     } 

     //Listen for ListView Item Click 
     view.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 

       if (expandedView[position]) { 
        // this is expanded view so toggle it back to brief view 
        expandedView[position] = false; 
       } else { 
        // clear any expanded views elsewhere 
        expandedView = new boolean[expandedView.length]; 
        // toggle brief view to expanded 
        expandedView[position] = true; 
       } 

       if (getItem(position) instanceof AnywallPost) { // only for branches 
        // AnywallPost branch = (AnywallPost) getItem(position); 
        // Toast.makeText(context, branch.getText(), Toast.LENGTH_LONG).show(); 
       } 

       // forces the ListView to refresh and convert the brief view into an expanded view and vice versa. 
       notifyDataSetChanged(); 
      } 
     }); 

     if (expandedView[position]) { 
      // ... add all your event listeners for the expanded view widgets 
     } 

     return view; 
    } 
} 
+0

感謝它的工作。但我想對銀行佈局做一些細微的修改,其中第一個包含徽標和分支數量,並且可以切換。其餘的同樣沒有變化。非常感謝:) – Mariam

+0

我試圖添加徽標到第一行,但我的應用程序崩潰,因爲字符串不能被投到AnywallPost。我添加這些行branch =(AnywallPost)getItem(position); imageLoader.DisplayImage(branch.getimg(), \t \t \t \t holder.logo); – Mariam

+0

要做到這一點,你應該有另一個對象來保存銀行名稱,圖像和分行數量。我將這添加到代碼中。對於切換,您可以調整onClick()代碼,使其適用於銀行以及分行。 –