1509
This commit is contained in:
parent
2f0293103c
commit
a15f6bad8f
@ -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>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user