项目要求
完善通讯录模块,展示联系人信息,有增加操作
项目展示
核心代码
XML代码
top.xml
添加了一个“+”按钮
tab03.xml
放置了一个recyclerview
item_contact.xml
联系人展示页面recyclerview的item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_margin="5dp"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/rl_parent"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#6495ED">
<TextView
android:id="@+id/tv_team"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="@android:color/white"
tools:text="主布局" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_child"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#B0C4DE"
android:visibility="gone">
<TextView
android:id="@+id/tv_team_child"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="@android:color/white"
tools:text="副布局" />
</RelativeLayout>
</LinearLayout>
item_contact.xml_add
联系人添加页面的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加联系人"
android:textSize="18dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="输入姓名" />
<EditText
android:id="@+id/et_contact_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="输入电话" />
<EditText
android:id="@+id/et_contact_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone" />
</LinearLayout>
Java代码
contactAdapter
package com.example.example1.mywechat;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import java.util.Map;
public class contactAdapter extends RecyclerView.Adapter<contactAdapter.contactviewholder> {
// private List<String>list;
private List<Map<String,String>> data;
private Context context;
private View inflater;
private int expandedPosition = -1;
private contactviewholder mViewHolder;
public contactAdapter(Context context, List<Map<String,String>>data) {
this.context=context;
//this.list=list;
this.data=data;
}
@Override
public contactAdapter.contactviewholder onCreateViewHolder(ViewGroup parent, int viewType) {
inflater= LayoutInflater.from(context).inflate(R.layout.item_contact,parent,false);
return new contactviewholder(inflater);
}
@Override
public void onBindViewHolder(final contactAdapter.contactviewholder holder, int position) {
//holder.tvTeam.setText(list.get(position));
//holder.tvTeamChild.setText(list.get(position) + "的联系方式");
holder.tvTeam.setText(data.get(position).get("name"));
holder.tvTeamChild.setText("电话:"+data.get(position).get("phoneNumber"));
final boolean isExpanded = position == expandedPosition;
holder.rlChild.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
holder.rlParent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mViewHolder != null) {
mViewHolder.rlChild.setVisibility(View.GONE);
notifyItemChanged(expandedPosition);
}
expandedPosition = isExpanded ? -1 : holder.getAdapterPosition();
mViewHolder = isExpanded ? null : holder;
notifyItemChanged(holder.getAdapterPosition());
}
});
}
// @Override
// public int getItemCount() { return list.size();}
@Override
public int getItemCount() { return data.size();}
class contactviewholder extends RecyclerView.ViewHolder{
RelativeLayout rlParent, rlChild;
TextView tvTeam, tvTeamChild;
public contactviewholder(View itemView) {
super(itemView);
rlParent = itemView.findViewById(R.id.rl_parent);
rlChild = itemView.findViewById(R.id.rl_child);
tvTeam = itemView.findViewById(R.id.tv_team);
tvTeamChild = itemView.findViewById(R.id.tv_team_child);
}
}
}
contactFragment
package com.example.example1.mywechat;
import android.animation.Animator;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.example1.mywechat.friends.Friend;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A simple {@link Fragment} subclass.
*/
public class contactFragment extends Fragment {
private RecyclerView recyclerView;
//private List<String> mList = new ArrayList<>();
private List<Map<String,String>>data=new ArrayList<Map<String, String>>();
private HashMap<String, String> item;
private Context context;
private contactAdapter adapter;
private boolean isGetData = false;
public contactFragment() {
// Required empty public constructor
}
@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
if(enter&&!isGetData){
isGetData = true;
data.clear();
initexpandData();
}else {
isGetData = false;
}
return super.onCreateAnimator(transit, enter, nextAnim);
}
public void onPause(){
super.onPause();
isGetData = false;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.tab03, container, false);
recyclerView=view.findViewById(R.id.rv_contacts);
context=this.getActivity();
initexpandData();
adapter=new contactAdapter(context,data);
LinearLayoutManager manager=new LinearLayoutManager(context);
manager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
return view;
}
public void initexpandData(){
Uri uri= ContactsContract.Contacts.CONTENT_URI;
ContentResolver resolver = context.getContentResolver();
Cursor cursor=resolver.query(uri, null, null, null, null); //得到记录集
if(cursor!=null){
while(cursor.moveToNext()){
//先获取联系人_id字段的索引号后再获取_id值
int idFieldIndex=cursor.getColumnIndex("_id");
int id=cursor.getInt(idFieldIndex);
//先获取联系人姓名字段的索引号后再获取姓名字段值
int nameFieldIndex = cursor.getColumnIndex("display_name");
String name=cursor.getString(nameFieldIndex);
int numCountFieldIndex=cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
int numCount=cursor.getInt(numCountFieldIndex); //获取联系人的电话号码个数
String phoneNumber="";
if(numCount>0){ //联系人有至少一个电话号码
//在类ContactsContract.CommonDataKinds.Phone中根据id查询相应联系人的所有电话;
Cursor phonecursor=getActivity().getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"=?",
new String[]{Integer.toString(id)}, null);
if(phonecursor!=null){
if(phonecursor.moveToFirst()){ //仅读取第一个电话号码
int numFieldIndex=phonecursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
phoneNumber=phonecursor.getString(numFieldIndex);
}
phonecursor.close();
}
}
item=new HashMap<String,String>(); //必须循环创建
item.put("name", name);
item.put("phoneNumber", phoneNumber);
data.add(item);
}
cursor.close();
}
}
}
MainActivity
case R.id.id_add_img:
final View addDialog=getLayoutInflater().inflate(R.layout.item_contact_add,null);
new AlertDialog.Builder(MainActivity.this).setView(addDialog).setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
EditText mname=(EditText)addDialog.findViewById(R.id.et_contact_name);
EditText mphone=(EditText)addDialog.findViewById(R.id.et_contact_phone);
final String name=mname.getText().toString();
final String phone=mphone.getText().toString();
// 创建一个空的ContentValues
ContentValues values = new ContentValues();
// 向RawContacts.CONTENT_URI执行一个空值插入
// 目的是获取系统返回的rawContactId
Uri rawContactUri = getContentResolver().insert(
ContactsContract.RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
values.clear();
values.put(Data.RAW_CONTACT_ID, rawContactId);
// 设置内容类型
values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
// 设置联系人名字
values.put(StructuredName.GIVEN_NAME, name);
// 向联系人URI添加联系人名字
getContentResolver().insert(ContactsContract
.Data.CONTENT_URI, values);
values.clear();
values.put(Data.RAW_CONTACT_ID, rawContactId);
values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
// 设置联系人的电话号码
values.put(Phone.NUMBER, phone);
// 设置电话类型
values.put(Phone.TYPE, Phone.TYPE_MOBILE);
// 向联系人电话号码URI添加电话号码
getContentResolver().insert(ContactsContract
.Data.CONTENT_URI, values);
values.clear();
contactFragment a = new contactFragment();
selectFragment(2);
Toast.makeText(MainActivity.this, "联系人数据添加成功",
Toast.LENGTH_SHORT).show();
}
}).show();
项目小结
本次项目重新用起来了之前学过的recyclerview,如果用好确实是可以做出很多好看的效果。学会了可以调用系统的联系人,困难点在于各个界面之间的跳转,相对来说挺有挑战。