2010-09-30 27 views
28

Đây là ArrayAdapter của tôi. Tôi muốn làm cho điều này hiệu quả hơn bằng cách làm theo mô hình ViewHolder:Làm cách nào để tạo ArrayAdapter theo mẫu ViewHolder?

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html

nhưng không chắc chắn làm thế nào để thực hiện điều này.

UPDATE: ViewHolder Pattern

private class QuoteAdapter extends ArrayAdapter<Quote> { 

    private ArrayList<Quote> items; 
    // used to keep selected position in ListView 
    private int selectedPos = -1; // init value for not-selected 

    public QuoteAdapter(Context context, int textViewResourceId, ArrayList<Quote> items) { 
     super(context, textViewResourceId, items); 
     this.items = items; 
    } 

    public void setSelectedPosition(int pos) { 
     selectedPos = pos; 
     // inform the view of this change 
     notifyDataSetChanged(); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 
     ViewHolder holder; // to reference the child views for later actions 

     if (v == null) { 
      LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.mainrow, null); 

      // cache view fields into the holder 
      holder = new ViewHolder(); 
      holder.nameText = (TextView) v.findViewById(R.id.nameText); 
      holder.priceText = (TextView) v.findViewById(R.id.priceText); 
      holder.changeText = (TextView) v.findViewById(R.id.changeText); 

      // associate the holder with the view for later lookup 
      v.setTag(holder); 
     } 
     else { 
      // view already exists, get the holder instance from the view 
      holder = (ViewHolder)v.getTag(); 
     } 

     // change the row color based on selected state 
     if (selectedPos == position) { 
      v.setBackgroundResource(R.drawable.stocks_selected_gradient); 
      holder.nameText.setTextColor(Color.WHITE); 
      holder.priceText.setTextColor(Color.WHITE); 
      holder.changeText.setTextColor(Color.WHITE); 
     } else { 
      v.setBackgroundResource(R.drawable.stocks_gradient); 
      holder.nameText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
      holder.priceText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
      holder.changeText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
     } 

     Quote q = items.get(position); 
     if (q != null) { 
      if (holder.nameText != null) { 
       holder.nameText.setText(q.getSymbol()); 
      } 
      if (holder.priceText != null) { 
       holder.priceText.setText(q.getLastTradePriceOnly()); 
      } 
      if (holder.changeText != null) { 
       try { 
        float floatedChange = Float.valueOf(q.getChange()); 
        if (floatedChange < 0) { 
         if (selectedPos != position) 
          holder.changeText.setTextAppearance(getApplicationContext(), R.style.RedText); // red 
        } else { 
         if (selectedPos != position) 
          holder.changeText.setTextAppearance(getApplicationContext(), R.style.GreenText); // green 
        } 
       } catch (NumberFormatException e) { 
        System.out.println("not a number"); 
       } catch (NullPointerException e) { 
        System.out.println("null number"); 
       } 
       holder.changeText.setText(q.getChange() + " (" + q.getPercentChange() + ")"); 
      } 
     } 
     return v; 
    } 
} 
+0

Tôi đã tạo một công cụ trực tuyến để tạo mã ViewHolder từ một bố cục XML: http://www.buzzingandroid.com/tools/android-layout-finder/ – JesperB

Trả lời

44

Các ViewHolder về cơ bản là một ví dụ lớp tĩnh mà bạn liên kết với một cái nhìn khi nó được tạo ra, bộ nhớ đệm đứa trẻ xem bạn đang nhìn lên khi chạy. Nếu chế độ xem đã tồn tại, hãy truy lục phiên bản chủ sở hữu và sử dụng các trường của nó thay vì gọi số findViewById.

Trong trường hợp của bạn:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    ViewHolder holder; // to reference the child views for later actions 

    if (v == null) { 
     LayoutInflater vi = 
      (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.mainrow, null); 
     // cache view fields into the holder 
     holder = new ViewHolder(); 
     holder.nameText = (TextView) v.findViewById(R.id.nameText); 
     holder.priceText = (TextView) v.findViewById(R.id.priceText); 
     holder.changeText = (TextView) v.findViewById(R.id.changeText); 
     // associate the holder with the view for later lookup 
     v.setTag(holder); 
    } 
    else { 
     // view already exists, get the holder instance from the view 
     holder = (ViewHolder) v.getTag(); 
    } 
    // no local variables with findViewById here 

    // use holder.nameText where you were 
    // using the local variable nameText before 

    return v; 
} 

// somewhere else in your class definition 
static class ViewHolder { 
    TextView nameText; 
    TextView priceText; 
    TextView changeText; 
} 

caveat: Tôi không cố gắng để biên dịch này, vì vậy mang theo một hạt muối.

+0

Loại này liên quan đến câu hỏi tôi đã hỏi trước đó về chế độ xem tái chế. Bạn có biết bất kỳ phân tích hiệu suất nào được thực hiện trên chi phí tạo lượt xem không? – Falmarri

+0

@Falmarri Không cụ thể, không. Mẫu đặc biệt này là để tránh sự thiếu hiệu quả của 'findViewById' thay vì Xem tạo. Nó sẽ được đơn giản để làm cho một trường hợp thử nghiệm để làm phân tích của riêng bạn Xem lại sử dụng so với sáng tạo, tuy nhiên. Tôi nghi ngờ rằng phân tích cú pháp bố cục XML một mình sẽ là đủ nguyên nhân để đảm bảo tái sử dụng. Nếu Chế độ xem rất đơn giản và bố cục có lập trình, tôi không có kiến ​​thức trực tiếp về chi phí liên quan đến việc tạo. – codelark

+0

mã ví dụ tuyệt vời. Tôi đã triển khai mẫu chủ sở hữu chế độ xem. Kiểm tra v.setBackgroundResource() tôi đang làm điều đó một cách chính xác liên quan đến mô hình View Holder? –

Các vấn đề liên quan