android 练习之路 (八)
项目的github地址:https://github.com/Qunter/SearchAndCall
------------------------------------------------------------------------
上图
PS:也不知道为什么,自从加了融云之后在虚拟机里使用的时候一直会报俩错,估计应该是跟6.0的适配有关吧,不过真机不报错,并且也不影响使用,那就先这样放着吧
PPS:一开始账号打错了,我还真是老年人记忆力......囧
今天使用Bmob来实现好友关系的存储,融云的IM来实现好友间的聊天
先做好准备工作,融云的依赖添加好,首先是下最新的kit包,然后导入两个module,并且添加依赖
//融云IM依赖 compile project(':IMKit')
这里还有一些相关的设置,暂且不说,官网上有文档
这还不算完,因为这个程序里我们没有后台(竞赛提交作品要能直接演示,当然了,客观原因是我也不是很喜欢挂后台,挺麻烦的),所以我们得在客户端里实现后台的功能,所以我们需要导入一些融云的工具类
它们在哪下载呢,可以下载一个java的融云的后台demo,然后把其中的io.rong包复制过来,粘贴到项目里
这就算把先头工作做的差不多了,然后一步一步来
还是类似上一个活动模块的布局样式
activity_friend_info_fragm.xml
<?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="match_parent" android:layout_height="match_parent"> <android.support.design.widget.TabLayout android:id="@+id/friendTabLayout" android:layout_width="match_parent" android:layout_height="45dp" app:tabIndicatorColor="@android:color/black"/> <android.support.v4.view.ViewPager android:id="@+id/friendViewPaper" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout>
布局完了就是跟一个Activity
FriendInfoFragmActivity.java
public class FriendInfoFragmActivity extends Fragment { public static FriendInfoFragmActivity newInstance() { return new FriendInfoFragmActivity(); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.activity_friend_info_fragm, container, false); //Fragment+ViewPager+FragmentViewPager组合的使用 ViewPager viewPager = (ViewPager) view.findViewById(R.id.friendViewPaper); FriendPagerAdapter adapter = new FriendPagerAdapter(getActivity().getSupportFragmentManager(), getContext()); viewPager.setAdapter(adapter); //TabLayout TabLayout tabLayout = (TabLayout) view.findViewById(R.id.friendTabLayout); tabLayout.setupWithViewPager(viewPager); return view; } }
接着是建一个viewpager的adapter
FriendPagerAdapter.java
public class FriendPagerAdapter extends FragmentPagerAdapter { public final int COUNT = 2; private String[] titles = new String[]{"消息列表", "我的好友"}; private Context context; private Fragment conversationList; private Fragment conversationFragment = null; public FriendPagerAdapter(FragmentManager fm, Context context) { super(fm); this.context = context; } @Override public Fragment getItem(int position) { if(position==0){ conversationList = initConversationList();//获取融云会话列表的对象 return conversationList; }else if(position==1){ return FriendPageFragment.newInstance(); } return null; } @Override public int getCount() { return COUNT; } @Override public CharSequence getPageTitle(int position) { return titles[position]; } private Fragment initConversationList() { /** * appendQueryParameter对具体的会话列表做展示 */ if (conversationFragment == null) { ConversationListFragment listFragment = new ConversationListFragment(); Uri uri = Uri.parse("rong://" + context.getPackageName()).buildUpon() .appendPath("conversationList") .appendQueryParameter(Conversation.ConversationType.PRIVATE.getName(), "false")//设置私聊会话是否聚合显示 .appendQueryParameter(Conversation.ConversationType.GROUP.getName(), "true") // .appendQueryParameter(Conversation.ConversationType.PUBLIC_SERVICE.getName(), "false")//公共服务号 //.appendQueryParameter(Conversation.ConversationType.APP_PUBLIC_SERVICE.getName(), "false")//公共服务号 .appendQueryParameter(Conversation.ConversationType.DISCUSSION.getName(), "false")//设置私聊会话是否聚合显示 .appendQueryParameter(Conversation.ConversationType.SYSTEM.getName(), "false")//设置私聊会是否聚合显示 .build(); listFragment.setUri(uri); return listFragment; } else { return conversationFragment; } } }
左边是消息列表,这个用融云的消息列表,右边是好友列表,就需要我们自己定义了
从左至右吧
融云的消息列表
activity_conversation.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#000"> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_margin="15dp" android:text="rongCloud" android:textColor="#fff" android:textSize="18sp" /> </LinearLayout> <fragment android:id="@+id/conversation" android:name="io.rong.imkit.fragment.ConversationFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
然后是Activity
(不是我说,这个命名是真的有毒,这个类是从融云提供的demo上摘下来的,不过反正是他们内部实现的东西,先不改得了,忙完这两天再一起弄)
public class ConversationActivity extends FragmentActivity { private TextView mName; //private ImageView mPersionInformationIv; private Conversation.ConversationType mConversationType; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_conversation); Intent intent = getIntent(); mConversationType = Conversation.ConversationType.valueOf(intent.getData().getLastPathSegment().toUpperCase(Locale.getDefault())); //Log.e("log", mConversationType.getName()); mName = (TextView) findViewById(R.id.name); /* mPersionInformationIv = (ImageView) findViewById(R.id.persionInformationIv); if(mConversationType.getName().equals("private")){ mPersionInformationIv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent mIntent = new Intent(getApplicationContext(),UserInformationPage.class); Bundle bundle=new Bundle(); bundle.putString("userNickName", getIntent().getData().getQueryParameter("title")); mIntent.putExtras(bundle); startActivity(mIntent); } }); }else if(mConversationType.getName().equals("discussion")){ mPersionInformationIv.setVisibility(View.GONE); } */ String sId = getIntent().getData().getQueryParameter("targetId");//targetId:单聊即对方ID,群聊即群组ID String sName = getIntent().getData().getQueryParameter("title");//获取昵称 if (!TextUtils.isEmpty(sName)){ mName.setText(sName); }else { // sId //TODO 拿到id 去请求自己服务端 } } }
然后这个界面注册的方式不一样,这里也贴一下,其实官方文档有写
<!--会话界面--> <activity android:name=".activity.ConversationActivity" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:host="com.qunter.searchcall" android:pathPrefix="/conversation/" android:scheme="rong" /> </intent-filter> </activity>
然后就是好友列表的实现
activity_friend_list.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipe_refresh_friend" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_friend" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" android:scrollbars="vertical" /> </android.support.v4.widget.SwipeRefreshLayout>
item_friend_info.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView android:id="@+id/friend_card_view" 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="60dp" android:layout_marginBottom="2dp" android:layout_marginTop="2dp" android:clickable="true" app:cardBackgroundColor="@color/card_view_background_dark" app:cardCornerRadius="0dp" app:cardElevation="2dp"> <LinearLayout android:id="@+id/item_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:orientation="horizontal"> <ImageView android:id="@+id/item_useravatar" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginLeft="30dp" android:layout_marginRight="10dp" android:scaleType="fitCenter" android:src="@drawable/account_avatar" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/item_username" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_marginEnd="10dp" android:lineSpacingExtra="2dp" android:maxLines="1" android:padding="2dp" android:textColor="@color/font_normal" android:textSize="18sp" /> </RelativeLayout> </LinearLayout> </android.support.v7.widget.CardView>
左边直接new一个融云的会话列表就行,但是右边需要自己写
FriendPageFragment.java
public class FriendPageFragment extends Fragment implements RongIM.UserInfoProvider{ private SwipeRefreshLayout friendSwipeRefreshLayout; private FriendInfoListAdapter adapter; private List<UserInfo> loginUserFriendInfoList; private List<Friend> loginUserFriendRongList; private RecyclerView friendRecyclerView; private String loginUserFriendObjectID=""; private final int GETLOGINUSERFRIENDOBJECTID=0x00,GETLOGINUSERFRIENDLIST=0x01,FRIENDINFORMATIONLISTDOWNOVER=0x02; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case GETLOGINUSERFRIENDOBJECTID: getLoginUserFriendObjectID(); break; case GETLOGINUSERFRIENDLIST: getLoginUserFriendList(); break; case FRIENDINFORMATIONLISTDOWNOVER: loadFriendRecycleView(); initUserInfo(); friendSwipeRefreshLayout.setRefreshing(false); break; } } }; public static FriendPageFragment newInstance() { FriendPageFragment fragment = new FriendPageFragment(); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.activity_friend_list,container,false); friendSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_friend); friendSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { handler.sendEmptyMessage(GETLOGINUSERFRIENDLIST); } }); friendRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_friend); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); friendRecyclerView.setLayoutManager(layoutManager); handler.sendEmptyMessage(GETLOGINUSERFRIENDOBJECTID); return view; } /** * 获取用户好友列表的数据库表单中ID */ private void getLoginUserFriendObjectID(){ final BmobQuery<UserFriend> userObjectIDQuery = new BmobQuery<UserFriend>(); userObjectIDQuery.addWhereEqualTo("userID", BmobUser.getCurrentUser(UserInfo.class).getUserPhone()); userObjectIDQuery.findObjects(new FindListener<UserFriend>() { @Override public void done(List<UserFriend> object, BmobException e) { if(e==null){ loginUserFriendObjectID =object.get(0).getObjectId(); //Toast.makeText(getContext(), "loginUserFriendObjectID"+loginUserFriendObjectID, Toast.LENGTH_SHORT).show(); handler.sendEmptyMessage(GETLOGINUSERFRIENDLIST); }else{ } } }); } /** *获取用户好友列表数据 */ private void getLoginUserFriendList(){ UserFriend userFriend = new UserFriend(); // 查询好友列表内的所有用户,因此查询的是用户表 BmobQuery<UserInfo> userFriendQuery = new BmobQuery<UserInfo>(); userFriend.setObjectId(loginUserFriendObjectID); //userFriend是UserFriend表中的字段,用来存储所有该用户的好友关系的用户 userFriendQuery.addWhereRelatedTo("userFriend", new BmobPointer(userFriend)); userFriendQuery.findObjects(new FindListener<UserInfo>() { @Override public void done(List<UserInfo> object,BmobException e) { if(e==null){ loginUserFriendInfoList=object; Log.e("taggg", loginUserFriendInfoList.size()+"" ); Log.e("taggg", loginUserFriendInfoList.get(0).getUserNickname()+"" ); //Toast.makeText(getContext(), "成功加载好友列表数据"+userFriendInformationList.size(), Toast.LENGTH_SHORT).show(); handler.sendEmptyMessage(FRIENDINFORMATIONLISTDOWNOVER); }else{ Toast.makeText(getContext(), "加载好友列表数据失败"+e, Toast.LENGTH_SHORT).show(); } } }); } /** * 加载好友信息至RecycleView */ private void loadFriendRecycleView(){ adapter = new FriendInfoListAdapter(getContext(),loginUserFriendInfoList,friendRecyclerView); adapter.setOnItemClickListener(new FriendInfoListAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { RongIM.getInstance().startPrivateChat(getContext(), loginUserFriendInfoList.get(position).getUserPhone(), loginUserFriendInfoList.get(position).getUserNickname()); } }); friendRecyclerView.setAdapter(adapter); } /** * 储存好友相关信息:id,昵称,token */ private void initUserInfo() { loginUserFriendRongList = new ArrayList<Friend>(); loginUserFriendRongList.add(new Friend(BmobUser.getCurrentUser(UserInfo.class).getUserPhone(),BmobUser.getCurrentUser(UserInfo.class).getUserNickname(),BmobUser.getCurrentUser(UserInfo.class).getUserAvatar())); for(UserInfo userFriendInfo:loginUserFriendInfoList){ //好友内容为:id,昵称,头像url loginUserFriendRongList.add(new Friend(userFriendInfo.getUserPhone(),userFriendInfo.getUserNickname(),userFriendInfo.getUserAvatar())); } RongIM.setUserInfoProvider(this, true); } @Override public io.rong.imlib.model.UserInfo getUserInfo(String s) { for (Friend i : loginUserFriendRongList) { if (i.getUserId().equals(s)) { //Log.e(TAG, i.getPortraitUri()); return new io.rong.imlib.model.UserInfo(i.getUserId(), i.getName(), Uri.parse(i.getPortraitUri())); } } return null; } }
然后就需要写一个RecycleView的Adapter了
FriendInfoListAdapter.java
public class FriendInfoListAdapter extends RecyclerView.Adapter<FriendInfoListAdapter.ViewHolder>{ private List<UserInfo> loginUserFriendInfoList; private Context context; private RecyclerView recyclerView; private OnItemClickListener onItemClickListener; static class ViewHolder extends RecyclerView.ViewHolder{ private ImageView userAvatarImg; private TextView userNameTv; public ViewHolder(View view){ super(view); userAvatarImg = (ImageView) view.findViewById(R.id.item_useravatar); userNameTv = (TextView) view.findViewById(R.id.item_username); } } public FriendInfoListAdapter(Context context,List<UserInfo> loginUserFriendInfoList,RecyclerView recyclerView){ this.context = context; this.loginUserFriendInfoList = loginUserFriendInfoList; this.recyclerView = recyclerView; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_friend_info,parent,false); ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(final FriendInfoListAdapter.ViewHolder holder, final int position) { holder.setIsRecyclable(false); final UserInfo friendInfo = loginUserFriendInfoList.get(position); Glide.with(context).load(friendInfo.getUserAvatar()).bitmapTransform(new CropCircleTransformation(context)).into(holder.userAvatarImg); holder.userNameTv.setText(friendInfo.getUserNickname()); if(onItemClickListener != null){ //为ItemView设置监听器 holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = holder.getLayoutPosition(); onItemClickListener.onItemClick(holder.itemView,position); } }); } } @Override public int getItemCount() { return loginUserFriendInfoList.size(); } /** * 点击事件接口 */ public interface OnItemClickListener{ void onItemClick(View view, int position); } /** * 设置点击事件方法 */ public void setOnItemClickListener(OnItemClickListener onItemClickListener){ this.onItemClickListener = onItemClickListener; } }
然后回头看一眼,首先在MainActivity里应该初始化融云的服务
RongIM.init(this); initUserToken();
/** * 获取融云所需userID及token */ private void initUserToken(){ UserInfo loginUser = BmobUser.getCurrentUser(UserInfo.class); userID = loginUser.getUserPhone(); connectRongServer(loginUser.getRongToken()); } /** * 初始化登录用户的融云服务 */ private void connectRongServer(String token) { RongIM.connect(token, new RongIMClient.ConnectCallback() { @Override public void onSuccess(String userId) { if (userId.equals(userID)){ Toast.makeText(getApplicationContext(), userID+"成功连接", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(getApplicationContext(), userID+"连接失败", Toast.LENGTH_SHORT).show(); } } @Override public void onError(RongIMClient.ErrorCode errorCode) { // Log.e("onError", "onError userid:" + errorCode.getValue());//获取错误的错误码 Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT).show(); Log.e("MainActivity", "connect failure errorCode is : " + errorCode.getValue()); } @Override public void onTokenIncorrect() { Toast.makeText(getApplicationContext(), "TokenError", Toast.LENGTH_SHORT).show(); Log.e("MainActivity", "token is error ,please check token and appkey"); } }); }
实体类也需要完善一下了,我们现在还有很多其他需要的字段,以及融云所需的好友实体
UserInfo.java
public class UserInfo extends BmobUser { private String userNickname; private String userPhone; private String rongToken; //用户头像,先设置初始头像 private String userAvatar="http://bmob-cdn-8854.b0.upaiyun.com/2017/01/21/910615c0405f9bd280350b57f8dc180c.png"; public String getUserNickname() { return userNickname; } public void setUserNickname(String userNickname) { this.userNickname = userNickname; } public String getUserPhone() { return userPhone; } public void setUserPhone(String userPhone) { this.userPhone = userPhone; } public String getRongToken() { return rongToken; } public void setRongToken(String rongToken) { this.rongToken = rongToken; } public String getUserAvatar() { return userAvatar; } public void setUserAvatar(String userAvatar) { this.userAvatar = userAvatar; } }
UserFriend.java
public class UserFriend extends BmobObject { private String userID; private BmobRelation userFriend; public BmobRelation getUserFriend() { return userFriend; } public void setUserFriend(BmobRelation userFriend) { this.userFriend = userFriend; } public String getUserID() { return userID; } public void setUserID(String userID) { this.userID = userID; } }
Friend.java
public class Friend { private String userId; private String name; private String portraitUri; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPortraitUri() { return portraitUri; } public void setPortraitUri(String portraitUri) { this.portraitUri = portraitUri; } public Friend(String userId, String name, String portraitUri) { this.userId = userId; this.name = name; this.portraitUri = portraitUri; } }
行,然后把注册类完善一下
RegisterActivity.java
public class RegisterActivity extends BaseActivity implements View.OnClickListener{ private EditText usernameEt,passwordEt,userPhoneEt,userNicknameEt; private Button registerBtn,loginBtn; private UserInfo userInformation; private String rongToken="",userID=""; private final int ISREGISTER=0x00,GETRONGTOKEN=0x01,ALLSUCCESS=0x02,FAIL=0x03,BUILDUSERFRIENDLIST=0x04; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case ISREGISTER: isRegister(); break; case GETRONGTOKEN: new getRongToken(userPhoneEt.getText().toString().trim(),userNicknameEt.getText().toString().trim()).start(); break; case BUILDUSERFRIENDLIST: buildUserFriendList(); break; case ALLSUCCESS: register(); break; case FAIL: Toast.makeText(RegisterActivity.this,"获取Token失败 请检查网络和账号后重试", Toast.LENGTH_SHORT).show(); break; } } }; @Override protected void initVariablesAndService() { setIfImmersive(true); Bmob.initialize(this,"8da888d03200ff2f6b403d064b805d60"); } @Override protected void initViews(Bundle savedInstanceState) { setContentView(R.layout.activity_register); usernameEt = (EditText) findViewById(R.id.register_usernameEt); passwordEt = (EditText) findViewById(R.id.register_passwordEt); userPhoneEt = (EditText) findViewById(R.id.register_userPhoneEt); userNicknameEt = (EditText) findViewById(R.id.register_userNicknameEt); registerBtn = (Button) findViewById(R.id.register_registerBtn); registerBtn.setOnClickListener(this); loginBtn = (Button) findViewById(R.id.register_loginBtn); loginBtn.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.register_registerBtn: userID = userPhoneEt.getText().toString().trim(); handler.sendEmptyMessage(ISREGISTER); break; case R.id.register_loginBtn: startActivity(LoginActivity.class); this.finish(); break; } } /** * 判断账号是否已被注册 */ private void isRegister(){ String username = usernameEt.getText().toString().trim(); BmobQuery<UserInfo> query = new BmobQuery<UserInfo>(); query.addWhereEqualTo("username",username); query.findObjects(new FindListener<UserInfo>() { @Override public void done(List<UserInfo> list, BmobException e) { if (e==null&&list.size()==0){ handler.sendEmptyMessage(GETRONGTOKEN); }else { Toast.makeText(RegisterActivity.this,"您的账号已被使用 请更换", Toast.LENGTH_SHORT).show(); } } }); } /** * 注册账号至bmob */ private void register(){ userInformation = new UserInfo(); userInformation.setUsername(usernameEt.getText().toString().trim()); userInformation.setPassword(passwordEt.getText().toString().trim()); userInformation.setUserPhone(userPhoneEt.getText().toString().trim()); userInformation.setUserNickname(userNicknameEt.getText().toString().trim()); userInformation.setRongToken(rongToken); userInformation.signUp(new SaveListener<UserInfo>() { @Override public void done(UserInfo s, BmobException e) { if(e==null){ Toast.makeText(RegisterActivity.this,"注册成功", Toast.LENGTH_SHORT).show(); userInformation.login(new SaveListener<UserInfo>() { @Override public void done(UserInfo userInfo, BmobException e) { if(e==null){ Toast.makeText(RegisterActivity.this,"登录成功", Toast.LENGTH_SHORT).show(); startActivity(MainActivity.class); RegisterActivity.this.finish(); } } }); }else{ Log.e("失败代码",e.toString()); } } }); } class getRongToken extends Thread{ String userId;//定义线程内变量 String name; User rongAppInformation = new User("cpj2xarlc68cn", "9gRSABvb08W3YC");//融云APP信息 String Token = ""; public getRongToken(String userId, String name){//定义带参数的构造函数,达到初始化线程内变量的值 this.userId=userId; this.name=name; } @Override public void run() { try { //使用默认头像,但函数需要三参 Token=rongAppInformation.getToken(userId,name,"http://bmob-cdn-8854.b0.upaiyun.com/2017/01/21/910615c0405f9bd280350b57f8dc180c.png").getToken(); rongToken=Token ;//消息内容 handler.sendEmptyMessage(BUILDUSERFRIENDLIST); } catch (Exception e) { e.printStackTrace(); handler.sendEmptyMessage(FAIL); } } } /** * 如果用户此前没有生成好友列表的情况下,执行方法生成好友列表 */ private void buildUserFriendList(){ String loginUserID = userID; UserFriend userFriend = new UserFriend(); userFriend.setUserID(loginUserID); BmobRelation relation = new BmobRelation(); userFriend.setUserFriend(relation); userFriend.save(new SaveListener<String>() { @Override public void done(String s, BmobException e) { if(e==null){ //Toast.makeText(getApplicationContext(), "执行", Toast.LENGTH_SHORT).show(); handler.sendEmptyMessage(ALLSUCCESS); }else{ //Toast.makeText(getApplicationContext(), e+"错误", Toast.LENGTH_SHORT).show(); } } }); } }
然后还是要加个添加好友的页面,样式大概就先做到和之前的那个添加活动差不多吧
activity_friend_add.xml
<?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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:theme="@style/Theme.AppCompat.Light"> <ImageView android:id="@+id/friend_add_backBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:src="@drawable/ic_arrow_back_black_36dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="添加好友" android:textSize="22sp" android:textColor="#dd000000" /> </android.support.v7.widget.Toolbar> </android.support.design.widget.AppBarLayout> <LinearLayout android:id="@+id/friend_add_linearlayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <EditText android:id="@+id/friend_addEt" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:hint="请输入搜索用户的昵称" android:inputType="text" /> <Button android:id="@+id/friend_addBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="搜索"/> </LinearLayout> </LinearLayout>
FriendAddActivity.java
public class FriendAddActivity extends BaseActivity implements View.OnClickListener{ private EditText friendAddEt; private TextView friendAddTv; private ImageView friendAddBackBtn; private LinearLayout friendAddLinLayout,friendAddAskView; private String loginUserFriendObjectID="",loginUserFriendFriendObjectID=""; private UserInfo searchUser; private String searchUserAvatarUrl="",searchUserNickname=""; //用于标记是否已显示用户信息 private int flag = 0; final int ADDFRIENDASK = 0x00, DELFRIENDASK = 0x01, IFGETFRIENDLIST = 0x02, SEARCHUSERINFO = 0x03 ,SAVEUSERFRIENDLIST=0x04,GETFRIENDFRIENDOBJECT=0x05,SAVEFRIENDFRIENDLIST=0x06; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case IFGETFRIENDLIST: searchUserFriendObjectId(); break; case SEARCHUSERINFO: searchUserInfo(friendAddEt.getText().toString()); break; case ADDFRIENDASK: if (flag == 1) { friendAddLinLayout.removeView(friendAddAskView); flag = 0; } friendAddLinLayout.addView(addFriendAddAskView(searchUserAvatarUrl, searchUserNickname)); flag = 1; break; case SAVEUSERFRIENDLIST: addFriend(); break; case DELFRIENDASK: friendAddLinLayout.removeView(friendAddAskView); break; case GETFRIENDFRIENDOBJECT: searchFriendFriendInformation(); break; case SAVEFRIENDFRIENDLIST: saveFriendFriendList(); break; } } }; @Override protected void initVariablesAndService() { } @Override protected void initViews(Bundle savedInstanceState) { setContentView(R.layout.activity_friend_add); friendAddEt = (EditText) findViewById(R.id.friend_addEt); friendAddTv = (TextView) findViewById(R.id.friend_addBtn); friendAddBackBtn = (ImageView) findViewById(R.id.friend_add_backBtn); friendAddLinLayout = (LinearLayout) findViewById(R.id.friend_add_linearlayout); friendAddTv.setOnClickListener(this); friendAddBackBtn.setOnClickListener(this); handler.sendEmptyMessage(IFGETFRIENDLIST); } /** * bmob查询登录用户好友表ID */ private void searchUserFriendObjectId() { final BmobQuery<UserFriend> query = new BmobQuery<UserFriend>(); query.addWhereEqualTo("userID", BmobUser.getCurrentUser(UserInfo.class).getUserPhone()); query.findObjects(new FindListener<UserFriend>() { @Override public void done(List<UserFriend> object, BmobException e) { if (e == null) { loginUserFriendObjectID = object.get(0).getObjectId(); } } }); } /** * bmob查询某用户信息 */ private void searchUserInfo(String userNickname) { BmobQuery<UserInfo> query = new BmobQuery<UserInfo>(); query.addWhereEqualTo("userNickname", userNickname); query.findObjects(new FindListener<UserInfo>() { @Override public void done(List<UserInfo> object, BmobException e) { if (e == null) { searchUser = object.get(0); searchUserAvatarUrl = searchUser.getUserAvatar(); searchUserNickname = searchUser.getUserNickname(); handler.sendEmptyMessage(ADDFRIENDASK); //Toast.makeText(getApplicationContext(), user.getNickName()+"查询成功", Toast.LENGTH_SHORT).show(); } else { //Toast.makeText(getApplicationContext(), "查询失败"+e, Toast.LENGTH_SHORT).show(); } } }); } /** * 动态生成是否添加好友(显示用户信息)的控件 */ private LinearLayout addFriendAddAskView(String searchUserAvatarUrl, String searchUserNickname) { friendAddAskView = new LinearLayout(this); friendAddAskView.setOrientation(LinearLayout.HORIZONTAL); LinearLayout.LayoutParams llparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); friendAddAskView.setLayoutParams(llparams); ImageView touxiang = new ImageView(this); Glide.with(getApplicationContext()).load(searchUserAvatarUrl).into(touxiang); LinearLayout.LayoutParams txparams = new LinearLayout.LayoutParams(100, 100); txparams.setMargins(30, 15, 15, 15); touxiang.setLayoutParams(txparams); LinearLayout.LayoutParams unparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); unparams.setMargins(30, 0, 30, 0); TextView userName = new TextView(this); userName.setText(searchUserNickname); userName.setLayoutParams(unparams); userName.setGravity(Gravity.CENTER_VERTICAL); LinearLayout.LayoutParams btnparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); btnparams.setMargins(30, 0, 30, 0); Button add = new Button(this); //add.setBackgroundResource(R.drawable.background_button); add.setTextColor(Color.WHITE); add.setGravity(Gravity.CENTER); add.setText("添加好友"); add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handler.sendEmptyMessage(SAVEUSERFRIENDLIST); } }); add.setLayoutParams(btnparams); Button noAdd = new Button(this); //noAdd.setBackgroundResource(R.drawable.background_button); noAdd.setTextColor(Color.WHITE); noAdd.setGravity(Gravity.CENTER); noAdd.setText("取消"); noAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handler.sendEmptyMessage(DELFRIENDASK); } }); noAdd.setLayoutParams(btnparams); friendAddAskView.addView(touxiang); friendAddAskView.addView(userName); friendAddAskView.addView(add); friendAddAskView.addView(noAdd); return friendAddAskView; } /** * 储存登录用户好友关系 */ private void addFriend(){ UserFriend userFriend = new UserFriend(); userFriend.setObjectId(loginUserFriendObjectID); BmobRelation relation = new BmobRelation(); //将当前用户添加到多对多关联中 relation.add(searchUser); //多对多关联指向`post`的`likes`字段 userFriend.setUserFriend(relation); userFriend.update(new UpdateListener() { @Override public void done(BmobException e) { if (e == null) { //Toast.makeText(getApplicationContext(), "更新登录用户好友列表成功", Toast.LENGTH_SHORT).show(); handler.sendEmptyMessage(GETFRIENDFRIENDOBJECT); } else { //Toast.makeText(getApplicationContext(), e+"添加失败", Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), loginUserFriendObjectID, Toast.LENGTH_SHORT).show(); } } }); } /** * bmob查询想添加为好友的用户的好友信息 */ private void searchFriendFriendInformation() { final BmobQuery<UserFriend> query = new BmobQuery<UserFriend>(); query.addWhereEqualTo("userID", searchUser.getUserPhone()); query.findObjects(new FindListener<UserFriend>() { @Override public void done(List<UserFriend> object, BmobException e) { if (e == null) { loginUserFriendFriendObjectID = object.get(0).getObjectId(); handler.sendEmptyMessage(SAVEFRIENDFRIENDLIST); } else { } } }); } /** * 储存好友用户好友关系 */ private void saveFriendFriendList(){ UserFriend userFriend = new UserFriend(); userFriend.setObjectId(loginUserFriendFriendObjectID); BmobRelation relation = new BmobRelation(); //将当前用户添加到多对多关联中 relation.add(BmobUser.getCurrentUser(UserInfo.class)); //多对多关联指向`post`的`likes`字段 userFriend.setUserFriend(relation); userFriend.update(new UpdateListener() { @Override public void done(BmobException e) { if (e == null) { Toast.makeText(getApplicationContext(), "成功添加好友", Toast.LENGTH_SHORT).show(); finish(); } else { //Toast.makeText(getApplicationContext(), e+"添加失败", Toast.LENGTH_SHORT).show(); Log.e("错误",e+"" ); Toast.makeText(getApplicationContext(), e+"", Toast.LENGTH_SHORT).show(); } } }); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.friend_addBtn: handler.sendEmptyMessage(SEARCHUSERINFO); break; case R.id.friend_add_backBtn: finish(); break; } } }
行,先告一段落吧,快凌晨了,赶着去github上传一下代码,不然今天的绿点又没了(笑)