วัตถุประสงค์หลักของวิธีการเช่นคืออะไรsetTag()
และgetTag()
ของView
ประเภทวัตถุ?
ฉันคิดถูกแล้วว่าฉันสามารถเชื่อมโยงวัตถุจำนวนมากกับมุมมองเดียวได้หรือไม่
วัตถุประสงค์หลักของวิธีการเช่นคืออะไรsetTag()
และgetTag()
ของView
ประเภทวัตถุ?
ฉันคิดถูกแล้วว่าฉันสามารถเชื่อมโยงวัตถุจำนวนมากกับมุมมองเดียวได้หรือไม่
คำตอบ:
สมมติว่าคุณสร้างมุมมองที่คล้ายกัน คุณสามารถตั้งค่าOnClickListener
สำหรับแต่ละมุมมองทีละรายการ:
button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
...
จากนั้นคุณต้องสร้างonClick
วิธีการเฉพาะสำหรับแต่ละมุมมองแม้ว่าพวกเขาจะทำสิ่งที่คล้ายกันเช่น:
public void onClick(View v) {
doAction(1); // 1 for button1, 2 for button2, etc.
}
เนื่องจากonClick
มีเพียงหนึ่งพารามิเตอร์ a View
และต้องรับข้อมูลอื่นจากตัวแปรอินสแตนซ์หรือตัวแปรโลคัลสุดท้ายในขอบเขตการล้อมรอบ สิ่งที่เราต้องการจริงๆคือการได้รับข้อมูลจากมุมมองของตัวเอง
ใส่getTag
/ setTag
:
button1.setTag(1);
button2.setTag(2);
ตอนนี้เราสามารถใช้ OnClickListener เดียวกันสำหรับทุกปุ่ม:
listener = new OnClickListener() {
@Override
public void onClick(View v) {
doAction(v.getTag());
}
};
มันเป็นพื้นทางสำหรับมุมมองที่จะมีความทรงจำ
public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }
ควรทำเคล็ดลับสำหรับส่วนสี 20 เป็นเพียงตัวยึดตำแหน่งสำหรับการตรวจสอบตำแหน่งของมุมมองของคุณ
ฉันต้องการเพิ่มคำไม่กี่คำ
แม้ว่าการใช้get/setTag(Object)
ดูเหมือนจะมีประโยชน์มากในบางกรณีของรูปแบบ ViewHolder แต่ฉันขอแนะนำให้คิดสองครั้งก่อนใช้ในกรณีอื่น มีอีกวิธีการแก้ปัญหาอีกด้วยการออกแบบที่ดีกว่า
สาเหตุหลักคือรหัสเช่นนั้นจะไม่สามารถรับได้อย่างรวดเร็ว
ไม่ชัดเจนนักพัฒนาคนอื่น ๆ ที่คุณออกแบบไว้เพื่อเก็บเป็นแท็กในมุมมอง วิธีการsetTag/getTag
ไม่ได้อธิบายเลย
มันก็จัดเก็บซึ่งจะต้องมีและต้องถูกทิ้งเมื่อคุณต้องการObject
getTag
คุณสามารถรับความผิดพลาดที่ไม่คาดคิดได้ในภายหลังเมื่อคุณตัดสินใจเปลี่ยนประเภทของวัตถุที่เก็บไว้ในแท็ก
นี่คือเรื่องราวในชีวิตจริง: เรามีโครงการขนาดใหญ่ที่มีอะแดปเตอร์จำนวนมากการดำเนินการแบบอะซิงก์พร้อมมุมมองและอื่น ๆ ผู้พัฒนารายหนึ่งตัดสินใจที่จะใช้รหัสset/getTag
ในส่วนของเขา แต่อีกคนหนึ่งได้ตั้งค่าแท็กเป็นมุมมองนี้แล้ว ในท้ายที่สุดคนไม่สามารถหาแท็กของเขาเองและสับสนมาก มีค่าใช้จ่ายเราหลายชั่วโมงในการค้นหาข้อผิดพลาด
setTag(int key, Object tag)
ดูดีขึ้นมากทำให้คุณสามารถสร้างคีย์ที่ไม่ซ้ำกันสำหรับทุกแท็ก (โดยใช้ทรัพยากร id ) แต่มีข้อ จำกัด ที่สำคัญสำหรับ Android <4.0 จาก Lint docs:
ก่อนหน้า Android 4.0 การใช้งาน View.setTag (int, Object) จะเก็บวัตถุไว้ในแผนที่แบบคงที่ซึ่งมีการอ้างอิงค่าอย่างมาก ซึ่งหมายความว่าหากวัตถุนั้นมีการอ้างอิงใด ๆ ที่ชี้ไปที่บริบทบริบท (ซึ่งชี้ไปที่ทุกสิ่งอื่น ๆ ) จะรั่วไหล หากคุณผ่านมุมมองมุมมองจะให้การอ้างอิงกับบริบทที่สร้างขึ้น ในทำนองเดียวกันผู้ถือมุมมองมักจะมีมุมมองและเคอร์เซอร์บางครั้งก็เชื่อมโยงกับมุมมอง
เราสามารถใช้setTag()
และgetTag()
การตั้งค่าและรับวัตถุที่กำหนดเองตามความต้องการของเรา setTag()
วิธีใช้อาร์กิวเมนต์พิมพ์Object
และส่งกลับgetTag()
Object
ตัวอย่างเช่น,
Person p = new Person();
p.setName("Ramkailash");
p.setId(2000001);
button1.setTag(p);
สำหรับนักพัฒนาเว็บนี้น่าจะเทียบเท่ากับ data- ..
สิ่งนี้มีประโยชน์มากสำหรับการArrayAdapter
ใช้งานที่กำหนดเอง เป็นการเพิ่มประสิทธิภาพบางอย่าง มีsetTag
ใช้เป็นข้อมูลอ้างอิงไปยังวัตถุที่อ้างอิงในบางส่วนของรูปแบบ (ที่แสดงในListView
) findViewById
แทน
static class ViewHolder {
TextView tvPost;
TextView tvDate;
ImageView thumb;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = myContext.getLayoutInflater();
convertView = inflater.inflate(R.layout.postitem, null);
ViewHolder vh = new ViewHolder();
vh.tvPost = (TextView)convertView.findViewById(R.id.postTitleLabel);
vh.tvDate = (TextView)convertView.findViewById(R.id.postDateLabel);
vh.thumb = (ImageView)convertView.findViewById(R.id.postThumb);
convertView.setTag(vh);
}
....................
}
ไม่เหมือนกับ ID แท็กจะไม่ใช้เพื่อระบุมุมมอง แท็กเป็นส่วนเพิ่มเติมของข้อมูลที่สามารถเชื่อมโยงกับมุมมองได้ ส่วนใหญ่มักจะใช้เพื่อความสะดวกในการจัดเก็บข้อมูลที่เกี่ยวข้องกับมุมมองในมุมมองของตัวเองแทนที่จะวางไว้ในโครงสร้างที่แยกต่างหาก
การอ้างอิง: http://developer.android.com/reference/android/view/View.html
การตั้งค่า TAG นั้นมีประโยชน์จริง ๆ เมื่อคุณมี ListView และต้องการรีไซเคิล / นำมุมมองนั้นมาใช้ซ้ำ ด้วยวิธีนี้ ListView จะคล้ายกับ RecyclerView รุ่นใหม่กว่ามาก
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
if ( convertView == null )
{
/* There is no view at this position, we create a new one.
In this case by inflating an xml layout */
convertView = mInflater.inflate(R.layout.listview_item, null);
holder = new ViewHolder();
holder.toggleOk = (ToggleButton) convertView.findViewById( R.id.togOk );
convertView.setTag (holder);
}
else
{
/* We recycle a View that already exists */
holder = (ViewHolder) convertView.getTag ();
}
// Once we have a reference to the View we are returning, we set its values.
// Here is where you should set the ToggleButton value for this item!!!
holder.toggleOk.setChecked( mToggles.get( position ) );
return convertView;
}