नए Gmail में संदर्भ क्रिया पट्टी के साथ एक सूची दृश्य बनाएं



हम क्या पाना चाहते हैं


पंक्ति आइकन पर क्लिक करके या उस पर लंबे समय तक दबाकर पंक्तियों का चयन करने की क्षमता के साथ एक सुचारू रूप से काम करने वाली सूची बनाएं। इसके अलावा, ताकि चयन व्यर्थ न हो, हमें उपयोगकर्ता को चयनित वस्तुओं के साथ कुछ क्रियाएं करने में सक्षम बनाना चाहिए।



एक सूची के लिए मार्कअप बनाना


तो, सबसे पहले, हमें एक लेआउट बनाने की आवश्यकता है जिसमें सूची स्थित होगी, यह इस तरह दिखता है:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </RelativeLayout> 

Android डेवलपर स्टूडियो द्वारा मेरे लिए बनाए गए कई पैड के अलावा, यहां कुछ भी दिलचस्प नहीं है। बस आपको याद दिलाने के लिए: android: id / list एक विशेष रूप से आवंटित आईडी है जो ListActivity और ListFragment को पता है।

अगला, एक ऐसा लेआउट बनाएं जो हमारे ListView में प्रत्येक पंक्ति में होगा:
 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="?android:attr/activatedBackgroundIndicator"> <View android:id="@+id/item_image" android:layout_width="45dp" android:layout_height="45dp" android:layout_margin="5dp" android:padding="10dp"/> <TextView android:id="@+id/item_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/item_image" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:text="TextView" android:layout_gravity="center_vertical|left" android:textAppearance="?android:textAppearanceListItem"> </TextView> </RelativeLayout> 

यहां हमारे पास एक टेक्स्ट व्यू है जो व्यू के दाईं ओर स्थित है। दृश्य के स्थान पर, आमतौर पर एक तस्वीर होती है, लेकिन इस उदाहरण में हम बस एक यादृच्छिक रूप से उत्पन्न रंग प्रदर्शित करेंगे।
एंड्रॉइड पर भी ध्यान दें : पृष्ठभूमि = "? एंड्रॉइड: एटीआर / सक्रियबैकग्राउंडइंडिएटर" लेआउट गुणों में। इस विशेषता के बिना, चयन का दृश्य प्रभाव दिखाई नहीं देगा।

एक सूची दृश्य बनाएं और उसे आबाद करें


मैं तुरंत गतिविधि कोड दूंगा और फिर उसे समझाऊंगा:
 public class MainActivity extends ListActivity { public static final String TAG = "FOR_HABR"; private Random randomGenerator = new Random(); @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //    int size = getRandomNumber(200); ListView listView = getListView(); //     Integer[] colors = generateListOfColors(size).toArray(new Integer[0]); ArrayAdapter<Integer> customAdapter = new CustomAdapter(this, R.layout.list_view_row, colors, listView); listView.setAdapter(customAdapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { Log.d(TAG, "onCreateOptionsMenu"); getMenuInflater().inflate(R.menu.main, menu); return true; } //     private List<Integer> generateListOfColors(int size) { List<Integer> result = new ArrayList<Integer>(); for (int i = 0; i < size; i++) { result.add(generateRandomColor()); } return result; } //   private int generateRandomColor() { return Color.rgb(getRandomNumber(256), getRandomNumber(256), getRandomNumber(256)); } private int getRandomNumber(int maxValue) { return randomGenerator.nextInt(maxValue); } } 

यहां हम सबसे पहले आईडी लेआउट ढूंढते हैं जिसमें हमारी शीट रखी जाएगी, और इसे इस गतिविधि की सामग्री असाइन करें। सूचना के साथ सूची दृश्य को पॉप्युलेट करने के लिए, शुरुआत में हम संख्याओं की एक सूची तैयार करते हैं और इसे हमारे कस्टम एडेप्टर के निर्माता को पास करते हैं।
अडैप्टर डेटा और डिस्प्ले के बीच एक सेतु है, इसमें हम सिस्टम को बताते हैं कि लिस्ट की प्रत्येक पंक्ति को हम कहाँ और किस घटक से देखना चाहेंगे। यहाँ हमारे एडेप्टर के लिए कोड है:
 public class CustomAdapter extends ArrayAdapter<Integer> { private ListView listView; public CustomAdapter(Context context, int textViewResourceId, Integer[] objects, ListView listView) { super(context, textViewResourceId, objects); this.listView = listView; } static class ViewHolder { TextView text; View indicator; } @Override public View getView(final int position, View convertView, ViewGroup parent) { Integer color = getItem(position); View rowView = convertView; // ,      if (rowView == null) { LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater(); rowView = inflater.inflate(R.layout.list_view_row, parent, false); ViewHolder h = new ViewHolder(); h.text = (TextView) rowView.findViewById(R.id.item_text); h.indicator = rowView.findViewById(R.id.item_image); rowView.setTag(h); } ViewHolder h = (ViewHolder) rowView.getTag(); h.text.setText("#" + Integer.toHexString(color).replaceFirst("ff", "")); h.indicator.setBackgroundColor(color); return rowView; } } 

हम मूल वर्ग से केवल एक विधि का पुनर्लेखन कर रहे हैं - getView पद्धति। इस विधि को हर बार कहा जाता है कि उपयोगकर्ता के विज़न के क्षेत्र में एक नई सूची पंक्ति दिखाई देती है। तदनुसार, हमें उस ऑब्जेक्ट को उस रूप में वापस करना होगा जिसमें हम उसे उपयोगकर्ता को दिखाना चाहते हैं।
यहां हम एक लोकप्रिय टेम्पलेट का उपयोग करते हैं जो हमें ऑब्जेक्ट्स को पुन: उपयोग करके लिस्ट व्यू के प्रदर्शन को थोड़ा (15% तक) बढ़ाने की अनुमति देता है। आप यहाँ इस टेम्पलेट के बारे में अधिक पढ़ सकते हैं।

इस स्तर पर, आप एप्लिकेशन शुरू कर सकते हैं, और हम रंगों के साथ एक सूची देखेंगे, लेकिन निश्चित रूप से, बिना किसी अन्तरक्रियाशीलता के।

एक श्रृंखला का चयन करने की क्षमता जोड़ें


ऐसा करने के लिए, निम्न कार्य करें:
 // ListView,       listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); //    listView.setMultiChoiceModeListener(new MultiChoiceImpl(listView)); 


हैंडलर इस तरह दिखता है:
 public class MultiChoiceImpl implements AbsListView.MultiChoiceModeListener { private AbsListView listView; public MultiChoiceImpl(AbsListView listView) { this.listView = listView; } @Override //        public void onItemCheckedStateChanged(ActionMode actionMode, int i, long l, boolean b) { Log.d(MainActivity.TAG, "onItemCheckedStateChanged"); int selectedCount = listView.getCheckedItemCount(); //     Context Action Bar setSubtitle(actionMode, selectedCount); } @Override //  CAB  xml public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { Log.d(MainActivity.TAG, "onCreateActionMode"); MenuInflater inflater = actionMode.getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { Log.d(MainActivity.TAG, "onPrepareActionMode"); return false; } @Override //     Item  AB public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { String text = "Action - " + menuItem.getTitle() + " ; Selected items: " + getSelectedFiles(); Toast.makeText(listView.getContext(), text , Toast.LENGTH_LONG).show(); return false; } @Override public void onDestroyActionMode(ActionMode actionMode) { Log.d(MainActivity.TAG, "onDestroyActionMode"); } private void setSubtitle(ActionMode mode, int selectedCount) { switch (selectedCount) { case 0: mode.setSubtitle(null); break; default: mode.setTitle(String.valueOf(selectedCount)); break; } } private List<String> getSelectedFiles() { List<String> selectedFiles = new ArrayList<String>(); SparseBooleanArray sparseBooleanArray = listView.getCheckedItemPositions(); for (int i = 0; i < sparseBooleanArray.size(); i++) { if (sparseBooleanArray.valueAt(i)) { Integer selectedItem = (Integer) listView.getItemAtPosition(sparseBooleanArray.keyAt(i)); selectedFiles.add("#" + Integer.toHexString(selectedItem).replaceFirst("ff", "")); } } return selectedFiles; } } 

आपने शायद देखा कि यहाँ हम एक नया एक्शन बार (संदर्भ_मेनू) ला रहे हैं। यह इस तरह दिखता है:
 <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/cab_add" android:icon="@android:drawable/ic_menu_add" android:orderInCategory="1" android:showAsAction="ifRoom" android:title="add"/> <item android:id="@+id/cab_share" android:icon="@android:drawable/ic_menu_share" android:orderInCategory="1" android:showAsAction="ifRoom" android:title="share"/> </menu> 

तो, अब क्रम में। ListView में, हम एक विशेष चयन मोड सेट करते हैं - CHOICE_MODE_MULTIPLE_MODAL , जिसका अर्थ है कि हम ListView वर्ग को पर्ची करते हैं जो AbsListView.MultiChoiceModeMististener इंटरफ़ेस को लागू करता है। इस वर्ग में, हम उन तरीकों को लागू करते हैं, जिनमें हम इंगित करते हैं कि हम चयन घटना के लिए क्या प्राप्त करना चाहते हैं, सीएबी में आइटम पर क्लिक करें या सीएबी को नष्ट करें।

अब यह आइकन पर क्लिक करके एक पंक्ति का चयन करने की क्षमता जोड़ने के लिए बनी हुई है। ऐसा करने के लिए, इसे GetView Method OnClickListener पर लटकाएँ:
 h.indicator.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { selectRow(v); } private void selectRow(View v) { listView.setItemChecked(position, !isItemChecked(position)); } private boolean isItemChecked(int pos) { SparseBooleanArray sparseBooleanArray = listView.getCheckedItemPositions(); return sparseBooleanArray.get(pos); } }); 

यहां, यदि पंक्ति पहले से ही चयनित है, तो अचयनित करें, अन्यथा चयन करें।

वह सब है। पूर्ण नमूना कोड मेरे BitBucket पर पाया जा सकता है।

युपीडी। इस आलेख में उपयोग की जाने वाली लगभग सभी चीज़ों को एपीआई 11 में जोड़ा गया था, और कुछ को 14. तक। इसलिए, यदि आप एपीआई <11 के साथ संगतता चाहते हैं, तो मैं आपको यहाँ देखने की सलाह देता हूँ।
वहाँ भी एक अद्भुत विकास कॉमरेड है - HoloEverywhere

Source: https://habr.com/ru/post/In185004/


All Articles