1509
This commit is contained in:
		| @@ -49,23 +49,19 @@ android { | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
|         // 二维码使用的类库 | ||||
|     api 'com.google.zxing:core:3.4.1' | ||||
|     api 'com.journeyapps:zxing-android-embedded:3.6.0' | ||||
|     implementation fileTree(dir: 'libs', include: ['*.jar']) | ||||
|      | ||||
|     api 'io.github.medyo:android-about-page:2.0.0' | ||||
|     api 'com.github.getActivity:ToastUtils:10.5' | ||||
|     api 'com.jcraft:jsch:0.1.55' | ||||
|     api 'org.jsoup:jsoup:1.13.1' | ||||
|     api 'com.squareup.okhttp3:okhttp:4.4.1' | ||||
|     // https://mvnrepository.com/artifact/com.github.open-android/pinyin4j | ||||
|     implementation 'com.github.open-android:pinyin4j:2.5.0' | ||||
|  | ||||
|     implementation 'io.github.medyo:android-about-page:2.0.0' | ||||
|     implementation 'com.github.getActivity:ToastUtils:10.5' | ||||
|      | ||||
|     api 'androidx.appcompat:appcompat:1.1.0' | ||||
|     api 'androidx.viewpager:viewpager:1.0.0' | ||||
|     api 'androidx.fragment:fragment:1.1.0' | ||||
|     api 'com.google.android.material:material:1.4.0' | ||||
|     implementation 'androidx.appcompat:appcompat:1.1.0' | ||||
|     implementation 'androidx.viewpager:viewpager:1.0.0' | ||||
|     implementation 'androidx.fragment:fragment:1.1.0' | ||||
|     implementation 'com.google.android.material:material:1.4.0' | ||||
|      | ||||
|     api 'cc.winboll.studio:libapputils:9.3.2' | ||||
|     api 'cc.winboll.studio:libappbase:1.5.6' | ||||
|      | ||||
|     api fileTree(dir: 'libs', include: ['*.jar']) | ||||
|     implementation 'cc.winboll.studio:libapputils:9.3.2' | ||||
|     implementation 'cc.winboll.studio:libappbase:1.5.6' | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| #Created by .winboll/winboll_app_build.gradle | ||||
| #Wed Feb 26 06:08:35 GMT 2025 | ||||
| #Wed Feb 26 06:42:40 GMT 2025 | ||||
| stageCount=4 | ||||
| libraryProject= | ||||
| baseVersion=1.0 | ||||
| publishVersion=1.0.3 | ||||
| buildCount=5 | ||||
| buildCount=8 | ||||
| baseBetaVersion=1.0.4 | ||||
|   | ||||
| @@ -5,9 +5,12 @@ package cc.winboll.studio.contacts.adapters; | ||||
|  * @Date 2025/02/26 13:35:44 | ||||
|  * @Describe ContactAdapter | ||||
|  */ | ||||
| import android.content.Intent; | ||||
| import android.net.Uri; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.Button; | ||||
| import android.widget.TextView; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
| @@ -19,6 +22,7 @@ public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactV | ||||
|  | ||||
|     public static final String TAG = "ContactAdapter"; | ||||
|  | ||||
|  | ||||
|     private List<ContactModel> contactList; | ||||
|  | ||||
|     public ContactAdapter(List<ContactModel> contactList) { | ||||
| @@ -34,9 +38,18 @@ public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactV | ||||
|  | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull ContactViewHolder holder, int position) { | ||||
|         ContactModel contact = contactList.get(position); | ||||
|         final ContactModel contact = contactList.get(position); | ||||
|         holder.contactName.setText(contact.getName()); | ||||
|         holder.contactNumber.setText(contact.getNumber()); | ||||
|  | ||||
|         holder.dialButton.setOnClickListener(new View.OnClickListener() { | ||||
|                 @Override | ||||
|                 public void onClick(View v) { | ||||
|                     String phoneNumber = contact.getNumber(); | ||||
|                     Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)); | ||||
|                     holder.itemView.getContext().startActivity(intent); | ||||
|                 } | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -47,11 +60,14 @@ public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactV | ||||
|     public class ContactViewHolder extends RecyclerView.ViewHolder { | ||||
|         TextView contactName; | ||||
|         TextView contactNumber; | ||||
|         Button dialButton; | ||||
|  | ||||
|         public ContactViewHolder(@NonNull View itemView) { | ||||
|             super(itemView); | ||||
|             contactName = itemView.findViewById(R.id.contact_name); | ||||
|             contactNumber = itemView.findViewById(R.id.contact_number); | ||||
|             dialButton = itemView.findViewById(R.id.dial_button); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -5,16 +5,48 @@ package cc.winboll.studio.contacts.beans; | ||||
|  * @Date 2025/02/26 13:37:00 | ||||
|  * @Describe ContactModel | ||||
|  */ | ||||
| import net.sourceforge.pinyin4j.PinyinHelper; | ||||
| import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; | ||||
| import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; | ||||
| import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; | ||||
| import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; | ||||
|  | ||||
| public class ContactModel { | ||||
|  | ||||
|     public static final String TAG = "ContactModel"; | ||||
|  | ||||
|     private String name; | ||||
|     private String number; | ||||
|     private String pinyin; | ||||
|  | ||||
|     public ContactModel(String name, String number) { | ||||
|         this.name = name; | ||||
|         this.number = number; | ||||
|         this.pinyin = convertToPinyin(name); | ||||
|     } | ||||
|  | ||||
|     private String convertToPinyin(String chinese) { | ||||
|         HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); | ||||
|         format.setCaseType(HanyuPinyinCaseType.LOWERCASE); | ||||
|         format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); | ||||
|  | ||||
|         StringBuilder pinyin = new StringBuilder(); | ||||
|         for (int i = 0; i < chinese.length(); i++) { | ||||
|             char ch = chinese.charAt(i); | ||||
|             if (Character.toString(ch).matches("[\\u4e00 - \\u9fa5]")) { | ||||
|                 try { | ||||
|                     String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch, format); | ||||
|                     if (pinyinArray != null) { | ||||
|                         pinyin.append(pinyinArray[0]); | ||||
|                     } | ||||
|                 } catch (BadHanyuPinyinOutputFormatCombination e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } else { | ||||
|                 pinyin.append(ch); | ||||
|             } | ||||
|         } | ||||
|         return pinyin.toString(); | ||||
|     } | ||||
|  | ||||
|     public String getName() { | ||||
| @@ -24,5 +56,9 @@ public class ContactModel { | ||||
|     public String getNumber() { | ||||
|         return number; | ||||
|     } | ||||
|  | ||||
|     public String getPinyin() { | ||||
|         return pinyin; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -10,9 +10,12 @@ import android.content.pm.PackageManager; | ||||
| import android.database.Cursor; | ||||
| import android.os.Bundle; | ||||
| import android.provider.ContactsContract; | ||||
| import android.text.Editable; | ||||
| import android.text.TextWatcher; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.EditText; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.core.app.ActivityCompat; | ||||
| @@ -36,7 +39,8 @@ public class ContactsFragment extends Fragment { | ||||
|     private RecyclerView recyclerView; | ||||
|     private ContactAdapter contactAdapter; | ||||
|     private List<ContactModel> contactList = new ArrayList<>(); | ||||
|  | ||||
|     private List<ContactModel> originalContactList = new ArrayList<>(); | ||||
|     private EditText searchEditText; | ||||
|  | ||||
|     public static ContactsFragment newInstance(int page) { | ||||
|         Bundle args = new Bundle(); | ||||
| @@ -54,10 +58,6 @@ public class ContactsFragment extends Fragment { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { | ||||
| @@ -72,6 +72,22 @@ public class ContactsFragment extends Fragment { | ||||
|         contactAdapter = new ContactAdapter(contactList); | ||||
|         recyclerView.setAdapter(contactAdapter); | ||||
|  | ||||
|         searchEditText = view.findViewById(R.id.search_edit_text); | ||||
|         searchEditText.addTextChangedListener(new TextWatcher() { | ||||
|                 @Override | ||||
|                 public void beforeTextChanged(CharSequence s, int start, int count, int after) { | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void onTextChanged(CharSequence s, int start, int before, int count) { | ||||
|                     filterContacts(s.toString()); | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 public void afterTextChanged(Editable s) { | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { | ||||
|             ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_READ_CONTACTS); | ||||
|         } else { | ||||
| @@ -91,6 +107,7 @@ public class ContactsFragment extends Fragment { | ||||
|  | ||||
|     private void readContacts() { | ||||
|         contactList.clear(); | ||||
|         originalContactList.clear(); | ||||
|         Cursor cursor = requireContext().getContentResolver().query( | ||||
|             ContactsContract.CommonDataKinds.Phone.CONTENT_URI, | ||||
|             null, | ||||
| @@ -102,10 +119,29 @@ public class ContactsFragment extends Fragment { | ||||
|             while (cursor.moveToNext()) { | ||||
|                 String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); | ||||
|                 String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); | ||||
|                 contactList.add(new ContactModel(name, number)); | ||||
|                 ContactModel contact = new ContactModel(name, number); | ||||
|                 contactList.add(contact); | ||||
|                 originalContactList.add(contact); | ||||
|             } | ||||
|             cursor.close(); | ||||
|             contactAdapter.notifyDataSetChanged(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void filterContacts(String query) { | ||||
|         contactList.clear(); | ||||
|         if (query.isEmpty()) { | ||||
|             contactList.addAll(originalContactList); | ||||
|         } else { | ||||
|             for (ContactModel contact : originalContactList) { | ||||
|                 if (contact.getName().toLowerCase().contains(query.toLowerCase()) || | ||||
|                     contact.getPinyin().toLowerCase().contains(query.toLowerCase()) || | ||||
|                     contact.getNumber().toLowerCase().contains(query.toLowerCase())) { | ||||
|                     contactList.add(contact); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         contactAdapter.notifyDataSetChanged(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -6,6 +6,13 @@ | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent"> | ||||
|  | ||||
|     <EditText | ||||
|         android:id="@+id/search_edit_text" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:hint="Search contacts" | ||||
|         android:padding="16dp"/> | ||||
|  | ||||
|     <androidx.recyclerview.widget.RecyclerView | ||||
|         android:id="@+id/contacts_recycler_view" | ||||
|         android:layout_width="match_parent" | ||||
|   | ||||
| @@ -1,24 +1,31 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <LinearLayout | ||||
| 	xmlns:android="http://schemas.android.com/apk/res/android" | ||||
| 	xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
| 	android:orientation="vertical" | ||||
| 	android:layout_width="wrap_content" | ||||
| 	android:layout_height="wrap_content"> | ||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
|     android:orientation="vertical" | ||||
|     android:padding="16dp"> | ||||
|  | ||||
| 	<TextView | ||||
| 		android:id="@+id/contact_name" | ||||
| 		android:layout_width="wrap_content" | ||||
| 		android:layout_height="wrap_content" | ||||
| 		android:textSize="16sp" | ||||
| 		android:textStyle="bold"/> | ||||
|     <TextView | ||||
|         android:id="@+id/contact_name" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:textSize="16sp" | ||||
|         android:textStyle="bold"/> | ||||
|  | ||||
| 	<TextView | ||||
| 		android:id="@+id/contact_number" | ||||
| 		android:layout_width="wrap_content" | ||||
| 		android:layout_height="wrap_content" | ||||
| 		android:textSize="14sp" | ||||
| 		android:layout_marginTop="4dp"/> | ||||
|     <TextView | ||||
|         android:id="@+id/contact_number" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:textSize="14sp" | ||||
|         android:layout_marginTop="4dp"/> | ||||
|  | ||||
|     <Button | ||||
|         android:id="@+id/dial_button" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:text="Dial" | ||||
|         android:layout_marginTop="8dp"/> | ||||
|  | ||||
| </LinearLayout> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ZhanGSKen
					ZhanGSKen