2012-04-22 7 views
7

मैं कॉमन्सवेयर एंड्रॉइड प्रोग्रामिंग ट्यूटोरियल के माध्यम से काम कर रहा हूं और ट्यूटोरियल 5 में, अतिरिक्त क्रेडिट 2, चुनौती है वस्तु सूची के "प्रकार नाम" के आधार पर सूची दृश्य में पंक्तियों को प्रदर्शित करने के लिए एकाधिक लेआउट का उपयोग करना (एक रेस्तरां का "प्रकार "विशेषता, जो एक स्ट्रिंग है)। इस प्रकार, यह एक कस्टम ArrayAdapter में getItemViewType और getViewTypeCount ओवरराइड करने का सुझाव देता है। इसके अलावा, android docs और अन्य online recipes या blog posts समान सुझाव देते हैं।व्यंजनों को ओवरराइडिंग को बढ़ावा देने के लिए क्यों करें ITemTiewType और getViewTypeCount प्राप्त करें जब यह आवश्यक प्रतीत नहीं होता है?

इस स्थिति में, इस नुस्खा के बाद और उन दो तरीकों को ओवरराइड करना ठीक काम करता है लेकिन उस रेस्तरां "प्रकार" विशेषता के मूल्य का निरीक्षण करने के आधार पर अनावश्यक तर्क होता है। उदाहरण के लिए (ध्यान दें कि इस अनुकूलक एक आंतरिक वर्ग है और restaurants बाहरी गतिविधि के एक सदस्य के रूप में घोषित रेस्तरां वस्तुओं की एक ArrayList है):

class RestaurantsAdapter extends ArrayAdapter<Restaurant> { 

    private static final int ROW_TYPE_DELIVERY = 0; 
    private static final int ROW_TYPE_TAKE_OUT = 1; 
    private static final int ROW_TYPE_SIT_DOWN = 2; 

    RestaurantsAdapter() { 
    super(LunchListActivity.this, android.R.layout.simple_list_item_1, restaurants); 
    } 

    public int getViewTypeCount() { 
    return 3; 
    } 

    public int getItemViewType(int position) { 
    String type = restaurants.get(position).getType(); 
    if (type == "delivery") { 
     return ROW_TYPE_DELIVERY; 
    } else if (type == "take_out") { 
     return ROW_TYPE_TAKE_OUT; 
    } else { 
     return ROW_TYPE_SIT_DOWN; 
    } 
    } 

    // Sets the icon, name and address of the Restaurant for the view. 
    public View getView(int position, View convertView, ViewGroup parent) { 
    View row = convertView; 
    RestaurantHolder viewHolder; 

    if (row == null) { 
     LayoutInflater inflater = getLayoutInflater(); 
     switch (getItemViewType(position)) { 
     case ROW_TYPE_DELIVERY: 
      row = inflater.inflate(R.layout.row_delivery, null); 
      break; 
     case ROW_TYPE_TAKE_OUT: 
      row = inflater.inflate(R.layout.row_take_out, null); 
      break; 
     default: 
      row = inflater.inflate(R.layout.row_sit_down, null); 
      break; 
     } 

     viewHolder = new RestaurantHolder(row); 
     row.setTag(viewHolder); 
    } else { 
     viewHolder = (RestaurantHolder)row.getTag(); 
    } 

    viewHolder.populateFrom(restaurants.get(position)); 

    return row; 
    } 

} 

क्या कीड़े मुझे डुप्लिकेट तर्क (यदि/बाकी getItemViewType में है और getView में)। तो, मैं निम्नलिखित करने के लिए अपने कार्यान्वयन बदल दिया है:

class RestaurantsAdapter extends ArrayAdapter<Restaurant> { 

    RestaurantsAdapter() { 
    super(LunchListActivity.this, android.R.layout.simple_list_item_1, restaurants); 
    } 

    // Sets the icon, name and address of the Restaurant for the view. 
    public View getView(int position, View convertView, ViewGroup parent) { 
    View row = convertView; 
    RestaurantHolder viewHolder; 

    if (row == null) { 
     LayoutInflater inflater = getLayoutInflater(); 
     if (restaurants.get(position).getType() == "delivery") { 
     row = inflater.inflate(R.layout.row_delivery, null); 
     } else if (restaurants.get(position).getType() == "take_out") { 
     row = inflater.inflate(R.layout.row_take_out, null); 
     } else { 
     row = inflater.inflate(R.layout.row_sit_down, null); 
     } 
     viewHolder = new RestaurantHolder(row); 
     row.setTag(viewHolder); 
    } else { 
     viewHolder = (RestaurantHolder)row.getTag(); 
    } 

    viewHolder.populateFrom(restaurants.get(position)); 

    return row; 
    } 

} 

इस गतिशील रूप से तीन एक्सएमएल लेआउट में से एक लोड हो रहा है के लक्ष्य को पूरा करता है, निरर्थक तर्क निकाल देता है, थोड़ा लेआउट की संख्या के लिए कोड का युग्मन कम कर देता है, और की आवश्यकता नहीं है ओवरराइडिंग getViewTypeCount और getItemViewType

मेरा प्रश्न है: अगर किसी को नहीं करना है तो उन दोनों तरीकों को क्यों ओवरराइड करना चाहिए?

उत्तर

16

किसी को दो तरीकों से ओवरराइड क्यों करना चाहिए यदि किसी को नहीं करना है?

कुछ दर्जन रेस्तरां, अलग-अलग प्रकार के रेस्तरां जोड़ें, और देखें कि जब आप स्क्रॉल करते हैं तो आपकी पंक्ति रीसाइक्लिंग घूमती है, ऊपर दिखाए गए आपके कार्यान्वयन को देखते हुए।

getItemViewType() और getViewTypeCount() यह सुनिश्चित करना है कि पंक्ति रीसाइक्लिंग कार्य करता है। एंड्रॉइड अलग ऑब्जेक्ट पूल बनाए रखेगा और केवल आपको सही प्रकार के रीसायकल पर एक पंक्ति वापस देगा।

अपने समाधान में, आप R.layout.row_delivery पंक्ति को बढ़ा सकते हैं, फिर बाद में इसे रीसाइक्लिंग के लिए वापस सौंप दिया जाए जब आपको वास्तव में R.layout.row_sit_down पंक्ति की आवश्यकता होती है।

बीटीडब्ल्यू, में inflate(R.layout.row_take_out, null) का उपयोग न करें। सही ढंग से संसाधित करने के लिए RelativeLayout नियम प्राप्त करने के लिए, inflate(R.layout.row_take_out, parent, false) का उपयोग करें।

+0

धन्यवाद मार्क; मुझे संदेह था कि मेरे संदेह रीसाइक्लिंग की गहरी समझ की कमी के कारण हैं। – ybakos

+0

@ybakos: यदि आपके पास वेस्क्रिप्शन है, तो रीसाइक्लिंग के अधिक गहन कवरेज के लिए "सूची के साथ फैंसी प्राप्त करना" अध्याय पढ़ें। – CommonsWare

संबंधित मुद्दे