নিম্নলিখিত কৌশলগুলি ব্যবহার করে এই পাঠটি আপনাকে দেখায় যে কীভাবে পরিচিতিগুলির একটি তালিকা পুনরুদ্ধার করতে হয় যার ডেটা সমস্ত বা সার্চ স্ট্রিংয়ের অংশের সাথে মেলে:
- পরিচিতির নাম মেলে
- পরিচিতির নামের ডেটার সমস্ত বা অংশের সাথে অনুসন্ধান স্ট্রিংকে মেলে পরিচিতিগুলির একটি তালিকা পুনরুদ্ধার করুন৷ পরিচিতি প্রদানকারী একই নামের একাধিক উদাহরণের অনুমতি দেয়, তাই এই কৌশলটি মিলের একটি তালিকা ফেরত দিতে পারে।
- একটি নির্দিষ্ট ধরনের ডেটা মেলে, যেমন একটি ফোন নম্বর
- একটি নির্দিষ্ট ধরনের বিস্তারিত তথ্য যেমন একটি ইমেল ঠিকানার সাথে সার্চ স্ট্রিং মেলে পরিচিতিগুলির একটি তালিকা পুনরুদ্ধার করুন৷ উদাহরণস্বরূপ, এই কৌশলটি আপনাকে সমস্ত পরিচিতির তালিকা করতে দেয় যার ইমেল ঠিকানা অনুসন্ধান স্ট্রিংয়ের সাথে মেলে।
- যেকোন ধরনের ডাটা মেলে
- নাম, ফোন নম্বর, রাস্তার ঠিকানা, ইমেল ঠিকানা, এবং আরও অনেক কিছু সহ যেকোন ধরণের বিশদ ডেটার সাথে অনুসন্ধান স্ট্রিংকে মেলে পরিচিতিগুলির একটি তালিকা পুনরুদ্ধার করুন৷ উদাহরণস্বরূপ, এই কৌশলটি আপনাকে একটি অনুসন্ধান স্ট্রিংয়ের জন্য যেকোনো ধরনের ডেটা গ্রহণ করতে এবং তারপরে সেই পরিচিতিগুলির তালিকা করতে দেয় যার জন্য ডেটা স্ট্রিংয়ের সাথে মেলে।
দ্রষ্টব্য: এই পাঠের সমস্ত উদাহরণ পরিচিতি প্রদানকারী থেকে ডেটা পুনরুদ্ধার করতে একটি CursorLoader
ব্যবহার করে। একটি CursorLoader
একটি থ্রেডে তার ক্যোয়ারী চালায় যা UI থ্রেড থেকে আলাদা। এটি নিশ্চিত করে যে ক্যোয়ারীটি UI প্রতিক্রিয়ার সময়কে ধীর করে না এবং একটি দুর্বল ব্যবহারকারীর অভিজ্ঞতার কারণ হয়। আরও তথ্যের জন্য, পটভূমিতে Android প্রশিক্ষণ ক্লাস লোডিং ডেটা দেখুন।
প্রদানকারী পড়ার অনুমতির অনুরোধ করুন
পরিচিতি প্রদানকারীর যেকোনো ধরনের অনুসন্ধান করতে, আপনার অ্যাপের অবশ্যই READ_CONTACTS
অনুমতি থাকতে হবে। এটির অনুরোধ করতে, এই <uses-permission>
উপাদানটিকে আপনার ম্যানিফেস্ট ফাইলে <manifest>
এর চাইল্ড এলিমেন্ট হিসেবে যোগ করুন :
<uses-permission android:name="android.permission.READ_CONTACTS" />
নাম দ্বারা একটি পরিচিতি মেলে এবং ফলাফল তালিকা
এই কৌশলটি যোগাযোগ প্রদানকারীর ContactsContract.Contacts
টেবিলে একটি পরিচিতি বা পরিচিতির নামের সাথে একটি অনুসন্ধান স্ট্রিং মেলাতে চেষ্টা করে। ব্যবহারকারীকে মিলিত পরিচিতিগুলির মধ্যে নির্বাচন করার অনুমতি দেওয়ার জন্য আপনি সাধারণত একটি ListView
এ ফলাফল প্রদর্শন করতে চান।
ListView এবং আইটেম লেআউট সংজ্ঞায়িত করুন
একটি ListView
এ অনুসন্ধান ফলাফল প্রদর্শন করতে, আপনার একটি প্রধান বিন্যাস ফাইলের প্রয়োজন যা ListView
সহ সমগ্র UI এবং একটি আইটেম বিন্যাস ফাইল যা ListView
এর একটি লাইনকে সংজ্ঞায়িত করে। উদাহরণস্বরূপ, আপনি নিম্নলিখিত XML দিয়ে res/layout/contacts_list_view.xml
প্রধান লেআউট ফাইল তৈরি করতে পারেন:
<?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent"/>
এই XML বিল্ট-ইন Android ListView
উইজেট android:id/list
ব্যবহার করে।
নিম্নলিখিত XML দিয়ে আইটেম লেআউট ফাইল contacts_list_item.xml
সংজ্ঞায়িত করুন:
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true"/>
এই XML বিল্ট-ইন Android TextView
উইজেট android:text1
ব্যবহার করে।
দ্রষ্টব্য: এই পাঠটি ব্যবহারকারীর কাছ থেকে একটি অনুসন্ধান স্ট্রিং পাওয়ার জন্য UI বর্ণনা করে না, কারণ আপনি পরোক্ষভাবে স্ট্রিং পেতে চাইতে পারেন। উদাহরণস্বরূপ, আপনি ব্যবহারকারীকে এমন পরিচিতিগুলি অনুসন্ধান করার জন্য একটি বিকল্প দিতে পারেন যার নাম একটি আগত পাঠ্য বার্তায় একটি স্ট্রিং এর সাথে মেলে।
আপনি যে দুটি লেআউট ফাইল লিখেছেন তা একটি ব্যবহারকারী ইন্টারফেসকে সংজ্ঞায়িত করে যা একটি ListView
দেখায়। পরবর্তী ধাপ হল কোড লিখতে যা এই UI ব্যবহার করে পরিচিতির তালিকা প্রদর্শন করতে।
পরিচিতির তালিকা প্রদর্শন করে এমন একটি খণ্ড সংজ্ঞায়িত করুন
পরিচিতিগুলির তালিকা প্রদর্শন করতে, একটি Activity
দ্বারা লোড করা একটি Fragment
সংজ্ঞায়িত করে শুরু করুন৷ একটি Fragment
ব্যবহার করা একটি আরও নমনীয় কৌশল, কারণ আপনি তালিকা প্রদর্শন করতে একটি Fragment
এবং ব্যবহারকারী তালিকা থেকে বেছে নেওয়া পরিচিতির বিবরণ প্রদর্শন করতে একটি দ্বিতীয় Fragment
ব্যবহার করতে পারেন। এই পদ্ধতিটি ব্যবহার করে, আপনি এই পাঠে উপস্থাপিত কৌশলগুলির একটিকে পাঠ থেকে একটি যোগাযোগের বিবরণ পুনরুদ্ধার করার সাথে একত্রিত করতে পারেন।
একটি Activity
থেকে এক বা একাধিক Fragment
অবজেক্ট কীভাবে ব্যবহার করবেন তা শিখতে, প্রশিক্ষণ ক্লাস পড়ুন ফ্র্যাগমেন্টের সাথে একটি গতিশীল UI তৈরি করুন ।
পরিচিতি প্রদানকারীর বিরুদ্ধে প্রশ্ন লিখতে আপনাকে সাহায্য করার জন্য, Android ফ্রেমওয়ার্ক ContactsContract
নামে একটি চুক্তির শ্রেণী প্রদান করে, যা প্রদানকারীকে অ্যাক্সেস করার জন্য দরকারী ধ্রুবক এবং পদ্ধতিগুলিকে সংজ্ঞায়িত করে৷ আপনি যখন এই ক্লাসটি ব্যবহার করেন, তখন আপনাকে সামগ্রীর URI, টেবিলের নাম বা কলামগুলির জন্য আপনার নিজস্ব ধ্রুবক সংজ্ঞায়িত করতে হবে না। এই ক্লাসটি ব্যবহার করতে, নিম্নলিখিত বিবৃতি অন্তর্ভুক্ত করুন:
কোটলিন
import android.provider.ContactsContract
জাভা
import android.provider.ContactsContract;
যেহেতু কোডটি প্রদানকারীর কাছ থেকে ডেটা পুনরুদ্ধার করতে একটি CursorLoader
ব্যবহার করে, তাই আপনাকে অবশ্যই উল্লেখ করতে হবে যে এটি লোডার ইন্টারফেস LoaderManager.LoaderCallbacks
প্রয়োগ করে। এছাড়াও, অনুসন্ধান ফলাফলের তালিকা থেকে ব্যবহারকারী কোন পরিচিতি নির্বাচন করবে তা সনাক্ত করতে সাহায্য করতে, অ্যাডাপ্টার ইন্টারফেসটি প্রয়োগ করুন AdapterView.OnItemClickListener
। যেমন:
কোটলিন
... import android.support.v4.app.Fragment import android.support.v4.app.LoaderManager import android.widget.AdapterView ... class ContactsFragment : Fragment(), LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
জাভা
... import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.widget.AdapterView; ... public class ContactsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
গ্লোবাল ভেরিয়েবলের সংজ্ঞা দাও
কোডের অন্যান্য অংশে ব্যবহৃত গ্লোবাল ভেরিয়েবলগুলিকে সংজ্ঞায়িত করুন:
কোটলিন
... /* * Defines an array that contains column names to move from * the Cursor to the ListView. */ @SuppressLint("InlinedApi") private val FROM_COLUMNS: Array<String> = arrayOf( if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)) { ContactsContract.Contacts.DISPLAY_NAME_PRIMARY } else { ContactsContract.Contacts.DISPLAY_NAME } ) /* * Defines an array that contains resource ids for the layout views * that get the Cursor column contents. The id is pre-defined in * the Android framework, so it is prefaced with "android.R.id" */ private val TO_IDS: IntArray = intArrayOf(android.R.id.text1) ... class ContactsFragment : Fragment(), LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener { ... // Define global mutable variables // Define a ListView object lateinit var contactsList: ListView // Define variables for the contact the user selects // The contact's _ID value var contactId: Long = 0 // The contact's LOOKUP_KEY var contactKey: String? = null // A content URI for the selected contact var contactUri: Uri? = null // An adapter that binds the result Cursor to the ListView private val cursorAdapter: SimpleCursorAdapter? = null
জাভা
... /* * Defines an array that contains column names to move from * the Cursor to the ListView. */ @SuppressLint("InlinedApi") private final static String[] FROM_COLUMNS = { Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME }; /* * Defines an array that contains resource ids for the layout views * that get the Cursor column contents. The id is pre-defined in * the Android framework, so it is prefaced with "android.R.id" */ private final static int[] TO_IDS = { android.R.id.text1 }; // Define global mutable variables // Define a ListView object ListView contactsList; // Define variables for the contact the user selects // The contact's _ID value long contactId; // The contact's LOOKUP_KEY String contactKey; // A content URI for the selected contact Uri contactUri; // An adapter that binds the result Cursor to the ListView private SimpleCursorAdapter cursorAdapter; ...
দ্রষ্টব্য: যেহেতু Contacts.DISPLAY_NAME_PRIMARY
জন্য Android 3.0 (API সংস্করণ 11) বা তার পরবর্তী সংস্করণ প্রয়োজন, তাই আপনার অ্যাপের minSdkVersion
10 বা তার নিচে সেট করা Android স্টুডিওতে একটি Android Lint সতর্কতা তৈরি করে। এই সতর্কতা বন্ধ করতে, FROM_COLUMNS
এর সংজ্ঞার আগে @SuppressLint("InlinedApi")
টীকা যোগ করুন।
খণ্ডটি শুরু করুন
Fragment
শুরু করুন। অ্যান্ড্রয়েড সিস্টেমের জন্য প্রয়োজনীয় খালি, পাবলিক কনস্ট্রাক্টর যোগ করুন এবং কলব্যাক পদ্ধতিতে Fragment
অবজেক্টের UI স্ফীত করুন onCreateView()
। যেমন:
কোটলিন
// A UI Fragment must inflate its View override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the fragment layout return inflater.inflate(R.layout.contact_list_fragment, container, false) }
জাভা
// Empty public constructor, required by the system public ContactsFragment() {} // A UI Fragment must inflate its View @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the fragment layout return inflater.inflate(R.layout.contact_list_fragment, container, false); }
ListView এর জন্য কার্সার অ্যাডাপ্টার সেট আপ করুন
SimpleCursorAdapter
সেট আপ করুন যা অনুসন্ধানের ফলাফলকে ListView
সাথে আবদ্ধ করে। পরিচিতিগুলি প্রদর্শন করে এমন ListView
অবজেক্ট পেতে, আপনাকে Fragment
মূল কার্যকলাপ ব্যবহার করে Activity.findViewById()
কল করতে হবে। আপনি setAdapter()
কল করার সময় পিতামাতার কার্যকলাপের Context
ব্যবহার করুন। যেমন:
কোটলিন
override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) ... // Gets the ListView from the View list of the parent activity activity?.also { contactsList = it.findViewById<ListView>(R.id.contact_list_view) // Gets a CursorAdapter cursorAdapter = SimpleCursorAdapter( it, R.layout.contact_list_item, null, FROM_COLUMNS, TO_IDS, 0 ) // Sets the adapter for the ListView contactsList.adapter = cursorAdapter } }
জাভা
public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ... // Gets the ListView from the View list of the parent activity contactsList = (ListView) getActivity().findViewById(R.layout.contact_list_view); // Gets a CursorAdapter cursorAdapter = new SimpleCursorAdapter( getActivity(), R.layout.contact_list_item, null, FROM_COLUMNS, TO_IDS, 0); // Sets the adapter for the ListView contactsList.setAdapter(cursorAdapter); }
নির্বাচিত পরিচিতি শ্রোতা সেট করুন
আপনি যখন একটি অনুসন্ধানের ফলাফল প্রদর্শন করেন, আপনি সাধারণত ব্যবহারকারীকে আরও প্রক্রিয়াকরণের জন্য একটি একক পরিচিতি নির্বাচন করার অনুমতি দিতে চান৷ উদাহরণস্বরূপ, যখন ব্যবহারকারী একটি পরিচিতিতে ক্লিক করে তখন আপনি একটি মানচিত্রে পরিচিতির ঠিকানা প্রদর্শন করতে পারেন। এই বৈশিষ্ট্যটি প্রদান করার জন্য, আপনি প্রথমে বর্তমান Fragment
ক্লিক লিসেনার হিসাবে সংজ্ঞায়িত করেছেন যে ক্লাসটি AdapterView.OnItemClickListener
প্রয়োগ করে, যেমনটি পরিচিতির তালিকা প্রদর্শন করে এমন একটি খণ্ড সংজ্ঞায়িত করুন বিভাগে দেখানো হয়েছে।
শ্রোতা সেট আপ চালিয়ে যেতে, onActivityCreated()
এ setOnItemClickListener()
পদ্ধতিতে কল করে এটিকে ListView
এ আবদ্ধ করুন। যেমন:
কোটলিন
fun onActivityCreated(savedInstanceState:Bundle) { ... // Set the item click listener to be the current fragment. contactsList.onItemClickListener = this ... }
জাভা
public void onActivityCreated(Bundle savedInstanceState) { ... // Set the item click listener to be the current fragment. contactsList.setOnItemClickListener(this); ... }
যেহেতু আপনি উল্লেখ করেছেন যে বর্তমান Fragment
হল ListView
জন্য OnItemClickListener
, আপনাকে এখন এটির প্রয়োজনীয় পদ্ধতি প্রয়োগ করতে হবে onItemClick()
, যা ক্লিক ইভেন্ট পরিচালনা করে। এটি একটি পরবর্তী বিভাগে বর্ণিত হয়েছে।
একটি অভিক্ষেপ সংজ্ঞায়িত করুন
একটি ধ্রুবক সংজ্ঞায়িত করুন যাতে কলামগুলি রয়েছে যা আপনি আপনার ক্যোয়ারী থেকে ফিরে আসতে চান। ListView
এর প্রতিটি আইটেম পরিচিতির ডিসপ্লে নাম প্রদর্শন করে, যা পরিচিতির নামের মূল রূপ ধারণ করে। Android 3.0 (API সংস্করণ 11) এবং পরবর্তীতে, এই কলামের নাম হল Contacts.DISPLAY_NAME_PRIMARY
; এর আগের সংস্করণে এর নাম Contacts.DISPLAY_NAME
৷DISPLAY_NAME৷
কলাম Contacts._ID
SimpleCursorAdapter
বাইন্ডিং প্রক্রিয়া দ্বারা ব্যবহৃত হয়। Contacts._ID
এবং LOOKUP_KEY
ব্যবহারকারীর দ্বারা নির্বাচন করা পরিচিতির জন্য একটি সামগ্রী URI তৈরি করতে একসাথে ব্যবহার করা হয়৷
কোটলিন
... @SuppressLint("InlinedApi") private val PROJECTION: Array<out String> = arrayOf( ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) ContactsContract.Contacts.DISPLAY_NAME_PRIMARY else ContactsContract.Contacts.DISPLAY_NAME )
জাভা
... @SuppressLint("InlinedApi") private static final String[] PROJECTION = { Contacts._ID, Contacts.LOOKUP_KEY, Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME };
কার্সার কলাম সূচীগুলির জন্য ধ্রুবক সংজ্ঞায়িত করুন
একটি Cursor
একটি পৃথক কলাম থেকে ডেটা পেতে, আপনার Cursor
মধ্যে কলামের সূচী প্রয়োজন। আপনি Cursor
কলামগুলির সূচীগুলির জন্য ধ্রুবকগুলি সংজ্ঞায়িত করতে পারেন, কারণ সূচীগুলি আপনার অভিক্ষেপের কলামের নামগুলির ক্রম হিসাবে একই। যেমন:
কোটলিন
// The column index for the _ID column private const val CONTACT_ID_INDEX: Int = 0 // The column index for the CONTACT_KEY column private const val CONTACT_KEY_INDEX: Int = 1
জাভা
// The column index for the _ID column private static final int CONTACT_ID_INDEX = 0; // The column index for the CONTACT_KEY column private static final int CONTACT_KEY_INDEX = 1;
নির্বাচনের মানদণ্ড উল্লেখ করুন
আপনি যে ডেটা চান তা নির্দিষ্ট করতে, টেক্সট এক্সপ্রেশন এবং ভেরিয়েবলের সংমিশ্রণ তৈরি করুন যা প্রদানকারীকে ডেটা কলামগুলি অনুসন্ধান করতে এবং মানগুলি খুঁজে বের করতে বলে৷
পাঠ্য অভিব্যক্তির জন্য, একটি ধ্রুবক সংজ্ঞায়িত করুন যা অনুসন্ধান কলামগুলি তালিকাভুক্ত করে। যদিও এই অভিব্যক্তিতে মানও থাকতে পারে, পছন্দের অনুশীলন হল "?" দিয়ে মানগুলিকে উপস্থাপন করা। স্থানধারক পুনরুদ্ধারের সময়, স্থানধারক একটি অ্যারের মান দিয়ে প্রতিস্থাপিত হয়। ব্যবহার করছেন "?" একটি স্থানধারক হিসাবে নিশ্চিত করে যে অনুসন্ধান স্পেসিফিকেশন SQL সংকলনের পরিবর্তে বাইন্ডিং দ্বারা তৈরি করা হয়েছে। এই অনুশীলনটি দূষিত SQL ইনজেকশনের সম্ভাবনাকে দূর করে। যেমন:
কোটলিন
// Defines the text expression @SuppressLint("InlinedApi") private val SELECTION: String = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} LIKE ?" else "${ContactsContract.Contacts.DISPLAY_NAME} LIKE ?" ... // Defines a variable for the search string private val searchString: String = ... // Defines the array to hold values that replace the ? private val selectionArgs = arrayOf<String>(searchString)
জাভা
// Defines the text expression @SuppressLint("InlinedApi") private static final String SELECTION = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Contacts.DISPLAY_NAME_PRIMARY + " LIKE ?" : Contacts.DISPLAY_NAME + " LIKE ?"; // Defines a variable for the search string private String searchString; // Defines the array to hold values that replace the ? private String[] selectionArgs = { searchString };
onItemClick() পদ্ধতি সংজ্ঞায়িত করুন
পূর্ববর্তী বিভাগে, আপনি ListView
এর জন্য আইটেম ক্লিক লিসেনার সেট করুন। এখন AdapterView.OnItemClickListener.onItemClick()
পদ্ধতিটি সংজ্ঞায়িত করে শ্রোতার জন্য ক্রিয়াটি বাস্তবায়ন করুন :
কোটলিন
override fun onItemClick(parent: AdapterView<*>, view: View?, position: Int, id: Long) { // Get the Cursor val cursor: Cursor? = (parent.adapter as? CursorAdapter)?.cursor?.apply { // Move to the selected contact moveToPosition(position) // Get the _ID value contactId = getLong(CONTACT_ID_INDEX) // Get the selected LOOKUP KEY contactKey = getString(CONTACT_KEY_INDEX) // Create the contact's content Uri contactUri = ContactsContract.Contacts.getLookupUri(contactId, mContactKey) /* * You can use contactUri as the content URI for retrieving * the details for a contact. */ } }
জাভা
@Override public void onItemClick( AdapterView<?> parent, View item, int position, long rowID) { // Get the Cursor Cursor cursor = parent.getAdapter().getCursor(); // Move to the selected contact cursor.moveToPosition(position); // Get the _ID value contactId = cursor.getLong(CONTACT_ID_INDEX); // Get the selected LOOKUP KEY contactKey = cursor.getString(CONTACT_KEY_INDEX); // Create the contact's content Uri contactUri = Contacts.getLookupUri(contactId, mContactKey); /* * You can use contactUri as the content URI for retrieving * the details for a contact. */ }
লোডার আরম্ভ করুন
যেহেতু আপনি ডেটা পুনরুদ্ধার করতে একটি CursorLoader
ব্যবহার করছেন, তাই আপনাকে অবশ্যই ব্যাকগ্রাউন্ড থ্রেড এবং অন্যান্য ভেরিয়েবলগুলি শুরু করতে হবে যা অ্যাসিঙ্ক্রোনাস পুনরুদ্ধার নিয়ন্ত্রণ করে। নিম্নলিখিত উদাহরণে দেখানো হিসাবে onCreate()
এ আরম্ভ করুন:
কোটলিন
class ContactsFragment : Fragment(), LoaderManager.LoaderCallbacks<Cursor> { ... override fun onCreate(savedInstanceState: Bundle?) { // Always call the super method first super.onCreate(savedInstanceState) ... // Initializes the loader loaderManager.initLoader(0, null, this)
জাভা
public class ContactsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { ... // Called just before the Fragment displays its UI @Override public void onCreate(Bundle savedInstanceState) { // Always call the super method first super.onCreate(savedInstanceState); ... // Initializes the loader getLoaderManager().initLoader(0, null, this);
ক্রিয়েটলোডারে প্রয়োগ করুন()
onCreateLoader()
পদ্ধতিটি প্রয়োগ করুন, যা আপনি initLoader()
কল করার সাথে সাথে লোডার ফ্রেমওয়ার্ক দ্বারা ডাকা হয়।
onCreateLoader()
এ, সার্চ স্ট্রিং প্যাটার্ন সেট আপ করুন। একটি প্যাটার্নে একটি স্ট্রিং তৈরি করতে, শূন্য বা তার বেশি অক্ষরের একটি ক্রম প্রতিনিধিত্ব করতে "%" (শতাংশ) অক্ষর সন্নিবেশ করান, বা একটি একক অক্ষর বা উভয়কে উপস্থাপন করতে "_" (আন্ডারস্কোর) অক্ষরগুলি উপস্থাপন করুন৷ উদাহরণস্বরূপ, "% জেফারসন%" প্যাটার্নটি "থমাস জেফারসন" এবং "জেফারসন ডেভিস" উভয়ের সাথে মিলবে।
পদ্ধতি থেকে একটি নতুন CursorLoader
ফেরত দিন। কন্টেন্ট URI-এর জন্য Contacts.CONTENT_URI
ব্যবহার করুন। এই URI পুরো টেবিলকে বোঝায়, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
... override fun onCreateLoader(loaderId: Int, args: Bundle?): Loader<Cursor> { /* * Makes search string into pattern and * stores it in the selection array */ selectionArgs[0] = "%$mSearchString%" // Starts the query return activity?.let { return CursorLoader( it, ContactsContract.Contacts.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, null ) } ?: throw IllegalStateException() }
জাভা
... @Override public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) { /* * Makes search string into pattern and * stores it in the selection array */ selectionArgs[0] = "%" + searchString + "%"; // Starts the query return new CursorLoader( getActivity(), ContactsContract.Contacts.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, null ); }
onLoadFinished() এবং onLoaderReset() প্রয়োগ করুন
onLoadFinished()
পদ্ধতি প্রয়োগ করুন। লোডার ফ্রেমওয়ার্ক onLoadFinished()
কল করে যখন পরিচিতি প্রদানকারী প্রশ্নের ফলাফল প্রদান করে। এই পদ্ধতিতে, SimpleCursorAdapter
এ ফলাফল Cursor
রাখুন। এটি স্বয়ংক্রিয়ভাবে অনুসন্ধান ফলাফলের সাথে ListView
আপডেট করে:
কোটলিন
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) { // Put the result Cursor in the adapter for the ListView cursorAdapter?.swapCursor(cursor) }
জাভা
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // Put the result Cursor in the adapter for the ListView cursorAdapter.swapCursor(cursor); }
onLoaderReset()
পদ্ধতিটি চালু করা হয় যখন লোডার ফ্রেমওয়ার্ক সনাক্ত করে যে ফলাফল Cursor
পুরানো ডেটা রয়েছে। বিদ্যমান Cursor
SimpleCursorAdapter
রেফারেন্স মুছুন। যদি আপনি না করেন, লোডার ফ্রেমওয়ার্ক Cursor
পুনর্ব্যবহার করবে না, যার ফলে মেমরি লিক হয়। যেমন:
কোটলিন
override fun onLoaderReset(loader: Loader<Cursor>) { // Delete the reference to the existing Cursor cursorAdapter?.swapCursor(null) }
জাভা
@Override public void onLoaderReset(Loader<Cursor> loader) { // Delete the reference to the existing Cursor cursorAdapter.swapCursor(null); }
আপনার কাছে এখন একটি অ্যাপের মূল অংশ রয়েছে যা যোগাযোগের নামের সাথে একটি অনুসন্ধান স্ট্রিংয়ের সাথে মেলে এবং একটি ListView
এ ফলাফল প্রদান করে। ব্যবহারকারী এটি নির্বাচন করতে একটি পরিচিতি নাম ক্লিক করতে পারেন. এটি একজন শ্রোতাকে ট্রিগার করে, যেখানে আপনি পরিচিতির ডেটা নিয়ে আরও কাজ করতে পারেন। উদাহরণস্বরূপ, আপনি পরিচিতির বিবরণ পুনরুদ্ধার করতে পারেন। এটি কীভাবে করবেন তা শিখতে, পরবর্তী পাঠটি চালিয়ে যান, একটি পরিচিতির বিবরণ পুনরুদ্ধার করুন ।
সার্চ ইউজার ইন্টারফেস সম্পর্কে আরও জানতে, API গাইডটি একটি সার্চ ইন্টারফেস তৈরি করুন পড়ুন।
এই পাঠের অবশিষ্ট অংশগুলি পরিচিতি প্রদানকারীতে পরিচিতিগুলি খোঁজার অন্যান্য উপায়গুলি প্রদর্শন করে৷
একটি নির্দিষ্ট ধরনের ডেটা দ্বারা একটি পরিচিতি মেলান
এই কৌশলটি আপনাকে আপনি যে ধরনের ডেটা মেলাতে চান তা নির্দিষ্ট করতে দেয়। নাম দ্বারা পুনরুদ্ধার করা এই ধরণের প্রশ্নের একটি নির্দিষ্ট উদাহরণ, তবে আপনি এটি কোনও পরিচিতির সাথে সম্পর্কিত যে কোনও ধরণের বিশদ ডেটার জন্যও করতে পারেন৷ উদাহরণস্বরূপ, আপনি একটি নির্দিষ্ট পোস্টাল কোড আছে যে পরিচিতি পুনরুদ্ধার করতে পারেন; এই ক্ষেত্রে, সার্চ স্ট্রিংটিকে একটি পোস্টাল কোড সারিতে সংরক্ষিত ডেটার সাথে মেলাতে হবে।
এই ধরনের পুনরুদ্ধার বাস্তবায়ন করতে, প্রথমে নিম্নলিখিত কোডটি প্রয়োগ করুন, যেমনটি পূর্ববর্তী বিভাগে তালিকাভুক্ত করা হয়েছে:
- প্রদানকারী পড়ার অনুমতির অনুরোধ করুন।
- ListView এবং আইটেম লেআউট সংজ্ঞায়িত করুন।
- পরিচিতির তালিকা প্রদর্শন করে এমন একটি খণ্ড সংজ্ঞায়িত করুন।
- গ্লোবাল ভেরিয়েবলের সংজ্ঞা দাও।
- খণ্ডটি শুরু করুন।
- ListView এর জন্য কার্সার অ্যাডাপ্টার সেট আপ করুন।
- নির্বাচিত পরিচিতি শ্রোতা সেট করুন।
- কার্সার কলাম সূচীগুলির জন্য ধ্রুবক সংজ্ঞায়িত করুন।
যদিও আপনি একটি ভিন্ন টেবিল থেকে ডেটা পুনরুদ্ধার করছেন, অভিক্ষেপের কলামগুলির ক্রম একই, তাই আপনি কার্সারের জন্য একই সূচী ব্যবহার করতে পারেন।
- onItemClick() পদ্ধতি সংজ্ঞায়িত করুন।
- লোডার আরম্ভ করুন।
- onLoadFinished() এবং onLoaderReset() প্রয়োগ করুন।
নিম্নলিখিত পদক্ষেপগুলি আপনাকে একটি বিশেষ ধরণের বিস্তারিত ডেটার সাথে একটি অনুসন্ধান স্ট্রিংকে মেলাতে এবং ফলাফলগুলি প্রদর্শন করতে প্রয়োজনীয় অতিরিক্ত কোড দেখায়৷
ডাটা টাইপ এবং টেবিল নির্বাচন করুন
একটি নির্দিষ্ট ধরনের বিস্তারিত ডেটা অনুসন্ধান করতে, আপনাকে ডেটা টাইপের জন্য কাস্টম MIME প্রকার মান জানতে হবে। প্রতিটি ডেটা টাইপের একটি অনন্য MIME প্রকার মান থাকে যা ডেটা প্রকারের সাথে সম্পর্কিত ContactsContract.CommonDataKinds
এর সাবক্লাসে একটি ধ্রুবক CONTENT_ITEM_TYPE
দ্বারা সংজ্ঞায়িত করা হয়। সাবক্লাসের নাম রয়েছে যা তাদের ডেটা টাইপ নির্দেশ করে; উদাহরণস্বরূপ, ইমেল ডেটার জন্য সাবক্লাস হল ContactsContract.CommonDataKinds.Email
, এবং ইমেল ডেটার জন্য কাস্টম MIME প্রকার ধ্রুবক Email.CONTENT_ITEM_TYPE
দ্বারা সংজ্ঞায়িত করা হয়।
আপনার অনুসন্ধানের জন্য ContactsContract.Data
টেবিল ব্যবহার করুন। আপনার প্রজেকশন, সিলেকশন ক্লজ এবং বাছাই ক্রমের জন্য আপনার প্রয়োজনীয় সমস্ত ধ্রুবক এই টেবিলের দ্বারা সংজ্ঞায়িত বা উত্তরাধিকারসূত্রে পাওয়া যায়।
একটি অভিক্ষেপ সংজ্ঞায়িত করুন
একটি প্রজেকশন সংজ্ঞায়িত করতে, ContactsContract.Data
এ সংজ্ঞায়িত এক বা একাধিক কলাম বা এটি যেগুলি থেকে উত্তরাধিকারসূত্রে পাওয়া যায় সেগুলি বেছে নিন। পরিচিতি প্রদানকারী সারি ফেরানোর আগে ContactsContract.Data
এবং অন্যান্য টেবিলের মধ্যে একটি অন্তর্নিহিত যোগদান করে। যেমন:
কোটলিন
@SuppressLint("InlinedApi") private val PROJECTION: Array<out String> = arrayOf( /* * The detail data row ID. To make a ListView work, * this column is required. */ ContactsContract.Data._ID, // The primary display name if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) ContactsContract.Data.DISPLAY_NAME_PRIMARY else ContactsContract.Data.DISPLAY_NAME, // The contact's _ID, to construct a content URI ContactsContract.Data.CONTACT_ID, // The contact's LOOKUP_KEY, to construct a content URI ContactsContract.Data.LOOKUP_KEY )
জাভা
@SuppressLint("InlinedApi") private static final String[] PROJECTION = { /* * The detail data row ID. To make a ListView work, * this column is required. */ ContactsContract.Data._ID, // The primary display name Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? ContactsContract.Data.DISPLAY_NAME_PRIMARY : ContactsContract.Data.DISPLAY_NAME, // The contact's _ID, to construct a content URI ContactsContract.Data.CONTACT_ID, // The contact's LOOKUP_KEY, to construct a content URI ContactsContract.Data.LOOKUP_KEY // A permanent link to the contact };
অনুসন্ধানের মানদণ্ড নির্ধারণ করুন
একটি নির্দিষ্ট ধরনের ডেটার মধ্যে একটি স্ট্রিং অনুসন্ধান করতে, নিম্নলিখিত থেকে একটি নির্বাচন ধারা তৈরি করুন:
- আপনার অনুসন্ধান স্ট্রিং ধারণকারী কলামের নাম। এই নামটি ডেটা টাইপ অনুসারে পরিবর্তিত হয়, তাই আপনাকে
ContactsContract.CommonDataKinds
এর সাবক্লাস খুঁজে বের করতে হবে যা ডেটা টাইপের সাথে মিলে যায় এবং তারপর সেই সাবক্লাস থেকে কলামের নাম বেছে নিন। উদাহরণস্বরূপ, ইমেল ঠিকানাগুলি অনুসন্ধান করতে,Email.ADDRESS
কলামটি ব্যবহার করুন। - অনুসন্ধান স্ট্রিং নিজেই, "?" হিসাবে উপস্থাপিত। নির্বাচন ধারায় অক্ষর।
- কাস্টম MIME প্রকার মান ধারণকারী কলামের নাম। এই নামটি সর্বদা
Data.MIMETYPE
হয়। - ডেটা টাইপের জন্য কাস্টম MIME প্রকার মান। পূর্বে বর্ণিত হিসাবে, এটি
ContactsContract.CommonDataKinds
সাবক্লাসে ধ্রুবকCONTENT_ITEM_TYPE
। উদাহরণস্বরূপ, ইমেল ডেটার জন্য MIME প্রকারের মান হলEmail.CONTENT_ITEM_TYPE
। ধ্রুবকের শুরু এবং শেষে একটি "'
" (একক উদ্ধৃতি) অক্ষর সংযুক্ত করে একক উদ্ধৃতিতে মানটি আবদ্ধ করুন; অন্যথায়, প্রদানকারী একটি স্ট্রিং মান হিসাবে পরিবর্তে একটি পরিবর্তনশীল নাম হিসাবে মান ব্যাখ্যা করে। এই মানটির জন্য আপনাকে একটি স্থানধারক ব্যবহার করতে হবে না, কারণ আপনি ব্যবহারকারীর দ্বারা সরবরাহকৃত মানের পরিবর্তে একটি ধ্রুবক ব্যবহার করছেন।
যেমন:
কোটলিন
/* * Constructs search criteria from the search string * and email MIME type */ private val SELECTION: String = /* * Searches for an email address * that matches the search string */ "${Email.ADDRESS} LIKE ? AND " + /* * Searches for a MIME type that matches * the value of the constant * Email.CONTENT_ITEM_TYPE. Note the * single quotes surrounding Email.CONTENT_ITEM_TYPE. */ "${ContactsContract.Data.MIMETYPE } = '${Email.CONTENT_ITEM_TYPE}'"
জাভা
/* * Constructs search criteria from the search string * and email MIME type */ private static final String SELECTION = /* * Searches for an email address * that matches the search string */ Email.ADDRESS + " LIKE ? " + "AND " + /* * Searches for a MIME type that matches * the value of the constant * Email.CONTENT_ITEM_TYPE. Note the * single quotes surrounding Email.CONTENT_ITEM_TYPE. */ ContactsContract.Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "'";
পরবর্তী, নির্বাচন যুক্তি ধারণ করতে ভেরিয়েবল সংজ্ঞায়িত করুন:
কোটলিন
private var searchString: String? = null private val selectionArgs: Array<String> = arrayOf("")
জাভা
String searchString; String[] selectionArgs = { "" };
ক্রিয়েটলোডারে প্রয়োগ করুন()
এখন আপনি যে ডেটা চান এবং এটি কীভাবে খুঁজে পাবেন তা নির্দিষ্ট করেছেন, onCreateLoader()
এর বাস্তবায়নে একটি প্রশ্ন সংজ্ঞায়িত করুন। আপনার অভিক্ষেপ, নির্বাচন পাঠ্য অভিব্যক্তি, এবং আর্গুমেন্ট হিসাবে নির্বাচন অ্যারে ব্যবহার করে এই পদ্ধতি থেকে একটি নতুন CursorLoader
ফেরত দিন। একটি সামগ্রী URI-এর জন্য, Data.CONTENT_URI
ব্যবহার করুন। যেমন:
কোটলিন
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> { // OPTIONAL: Makes search string into pattern searchString = "%$mSearchString%" searchString?.also { // Puts the search string into the selection criteria selectionArgs[0] = it } // Starts the query return activity?.let { CursorLoader( it, ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, null ) } ?: throw IllegalStateException() }
জাভা
@Override public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) { // OPTIONAL: Makes search string into pattern searchString = "%" + searchString + "%"; // Puts the search string into the selection criteria selectionArgs[0] = searchString; // Starts the query return new CursorLoader( getActivity(), Data.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, null ); }
এই কোড স্নিপেটগুলি একটি নির্দিষ্ট ধরণের বিশদ ডেটার উপর ভিত্তি করে একটি সাধারণ বিপরীত সন্ধানের ভিত্তি। আপনার অ্যাপটি যদি ইমেলের মতো একটি নির্দিষ্ট ধরণের ডেটার উপর ফোকাস করে এবং আপনি ব্যবহারকারীদের ডেটার একটি অংশের সাথে যুক্ত নাম পেতে অনুমতি দিতে চান তবে এটি ব্যবহার করার সর্বোত্তম কৌশল।
যে কোনো ধরনের তথ্য দ্বারা একটি পরিচিতি মেলে
যেকোন ধরনের ডেটার উপর ভিত্তি করে একটি পরিচিতি পুনরুদ্ধার করা পরিচিতিগুলিকে ফেরত দেয় যদি তাদের কোনও ডেটা সার্চ স্ট্রিংয়ের সাথে মেলে, নাম, ইমেল ঠিকানা, ডাক ঠিকানা, ফোন নম্বর এবং আরও অনেক কিছু। এর ফলে অনুসন্ধান ফলাফলের একটি বিস্তৃত সেট পাওয়া যায়। উদাহরণস্বরূপ, যদি সার্চ স্ট্রিংটি "Doe" হয়, তাহলে যেকোনো ডেটা টাইপ অনুসন্ধান করলে পরিচিতি "John Doe" ফিরে আসে; এটি "ডো স্ট্রিটে" বসবাসকারী পরিচিতিগুলিকেও ফিরিয়ে দেয়।
এই ধরনের পুনরুদ্ধার বাস্তবায়ন করতে, প্রথমে নিম্নলিখিত কোডটি প্রয়োগ করুন, যেমনটি পূর্ববর্তী বিভাগে তালিকাভুক্ত করা হয়েছে:
- প্রদানকারী পড়ার অনুমতির অনুরোধ করুন।
- ListView এবং আইটেম লেআউট সংজ্ঞায়িত করুন।
- পরিচিতির তালিকা প্রদর্শন করে এমন একটি খণ্ড সংজ্ঞায়িত করুন।
- গ্লোবাল ভেরিয়েবলের সংজ্ঞা দাও।
- খণ্ডটি শুরু করুন।
- ListView এর জন্য কার্সার অ্যাডাপ্টার সেট আপ করুন।
- নির্বাচিত পরিচিতি শ্রোতা সেট করুন।
- একটি অভিক্ষেপ সংজ্ঞায়িত করুন।
- কার্সার কলাম সূচীগুলির জন্য ধ্রুবক সংজ্ঞায়িত করুন।
এই ধরনের পুনরুদ্ধারের জন্য, আপনি বিভাগে যে টেবিলটি ব্যবহার করেছেন সেটিই ব্যবহার করছেন নাম অনুসারে একটি পরিচিতি মেলান এবং ফলাফল তালিকা করুন । একই কলামের সূচীগুলিও ব্যবহার করুন।
- onItemClick() পদ্ধতি সংজ্ঞায়িত করুন।
- লোডার আরম্ভ করুন।
- onLoadFinished() এবং onLoaderReset() প্রয়োগ করুন।
নিম্নলিখিত পদক্ষেপগুলি আপনাকে যেকোন ধরণের ডেটার সাথে একটি অনুসন্ধান স্ট্রিং মেলাতে এবং ফলাফলগুলি প্রদর্শন করতে প্রয়োজনীয় অতিরিক্ত কোড দেখায়৷
নির্বাচনের মানদণ্ড সরান
SELECTION
ধ্রুবক বা mSelectionArgs
ভেরিয়েবল সংজ্ঞায়িত করবেন না। এগুলি এই ধরণের পুনরুদ্ধারে ব্যবহৃত হয় না।
ক্রিয়েটলোডারে প্রয়োগ করুন()
onCreateLoader()
পদ্ধতি প্রয়োগ করুন, একটি নতুন CursorLoader
ফিরিয়ে দিন। আপনাকে অনুসন্ধান স্ট্রিংটিকে একটি প্যাটার্নে রূপান্তর করতে হবে না, কারণ পরিচিতি প্রদানকারী স্বয়ংক্রিয়ভাবে এটি করে। বেস URI হিসাবে Contacts.CONTENT_FILTER_URI
ব্যবহার করুন এবং Uri.withAppendedPath()
কল করে এতে আপনার অনুসন্ধান স্ট্রিং যুক্ত করুন। এই URI ব্যবহার করা স্বয়ংক্রিয়ভাবে যেকোনো ডেটা টাইপের জন্য অনুসন্ধান শুরু করে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
override fun onCreateLoader(loaderId: Int, args: Bundle?): Loader<Cursor> { /* * Appends the search string to the base URI. Always * encode search strings to ensure they're in proper * format. */ val contentUri: Uri = Uri.withAppendedPath( ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode(searchString) ) // Starts the query return activity?.let { CursorLoader( it, contentUri, PROJECTION2, null, null, null ) } ?: throw IllegalStateException() }
জাভা
@Override public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) { /* * Appends the search string to the base URI. Always * encode search strings to ensure they're in proper * format. */ Uri contentUri = Uri.withAppendedPath( Contacts.CONTENT_FILTER_URI, Uri.encode(searchString)); // Starts the query return new CursorLoader( getActivity(), contentUri, PROJECTION, null, null, null ); }
এই কোড স্নিপেটগুলি একটি অ্যাপের ভিত্তি যা পরিচিতি প্রদানকারীর একটি বিস্তৃত অনুসন্ধান করে৷ কৌশলটি এমন অ্যাপগুলির জন্য উপযোগী যেগুলি পিপল অ্যাপের পরিচিতি তালিকার স্ক্রিনের মতো কার্যকারিতা প্রয়োগ করতে চায়।