李晨晨:
本周我主要想实现发送图片的功能,这次我先实现了图片选择界面的相关功能,主要有图片展示用的RecycleViewAdapter和对应的RViewHolder。参考博文地址:https://blog.csdn.net/u014628886/article/details/52184027
构造一个比较完整的Adapter至少需要完成以下三件事情:
1.onCreateViewHolder通过视图id加载不同Item视图并生成ViewHolder用来保存每个列表Item视图。
2.onBindViewHolder更新列表Item视图(填充model数据)
3.新建ViewHolder类来存储Item视图及其子视图
- public abstract class RecycleViewAdapter<T> extends RecyclerView.Adapter<RViewHolder> {
- private Context mContext;
- private List<T> mList;
- private LayoutInflater mInflater;
- private OnItemClickListener mClickListener;
- public RecycleViewAdapter(Context context, List<T> data){
- this.mContext = context;
- this.mList = data;
- mInflater = LayoutInflater.from(mContext);
- }
- @Override
- public RViewHolder onCreateViewHolder(ViewGroup parent, int itemLayout) {
- View view = mInflater.inflate(itemLayout, parent, false);
- return new RViewHolder(mContext,view);
- }
- @Override
- public void onBindViewHolder(final RViewHolder holder, int position) {
- View view = holder.getConvertView();
- view.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mClickListener != null){
- mClickListener.onItemClick(holder,holder.getAdapterPosition());
- }
- }
- });
- bindView(holder,position);
- }
- @Override
- public int getItemViewType(int position) {
- return this.setItemLayoutId(position);
- }
- @Override
- public int getItemCount() {
- return mList == null ? 0 : mList.size();
- }
- /**
- * set item layout id
- * @param position item'position in list
- * @return layout id
- */
- public abstract int setItemLayoutId(int position);
- /**
- * bind view by holder
- * @param holder view holder
- * @param position position in data list
- */
- public abstract void bindView(RViewHolder holder, int position);
- public void setItemClickListener(OnItemClickListener clickListener){
- this.mClickListener = clickListener;
- }
- }
对应Item的点击事件,需要在onBindViewHolder中适当绑定点击事件。具体的实现要在使用该Adapter的activity中为adapter设置点击监听器。
- view.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mClickListener != null){
- mClickListener.onItemClick(holder,holder.getAdapterPosition());
- }
- }
对应的RviewHolder:
- public class RViewHolder extends RecyclerView.ViewHolder{
- private SparseArray<View> mViews;
- private View mConvertView;
- private Context mContext;
- public RViewHolder(Context context, View itemView) {
- super(itemView);
- mContext = context;
- mConvertView = itemView;
- mViews = new SparseArray<>();
- }
- private <T extends View> T getView(int viewId) {
- View view = mViews.get(viewId);
- if (view == null) {
- view = mConvertView.findViewById(viewId);
- mViews.put(viewId, view);
- }
- return (T) view;
- }
- public View getConvertView() {
- return mConvertView;
- }
- public ImageView getImageView(int viewId){
- return getView(viewId);
- }
- public void setText(int viewId, String text) {
- TextView tv = getView(viewId);
- tv.setText(text);
- }
- public void setVisible(int viewId, boolean visible) {
- View view = getView(viewId);
- view.setVisibility(visible ? View.VISIBLE : View.GONE);
- }
- public void setOnClickListener(int viewId, View.OnClickListener listener) {
- View view = getView(viewId);
- view.setOnClickListener(listener);
- }
- }
仝心:
这几天我继续完成了表情包的相关使用的编程部分,包括自定义一个继承自LinearLayout的表情选择指示器IndicatorView类用于表情页面切换。主要方法是init(count)方法,其中传入的count参数是表情包页数,页数的计算在另外的Java文件中实现。
- public void init(int count) {
- mImageViews = new ArrayList<>();
- this.removeAllViews();
- for (int i = 0; i < count; i++) {
- RelativeLayout rl = new RelativeLayout(mContext);
- LayoutParams params = new LayoutParams(mMaxWidth, mMaxHeight);
- RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
- LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
- layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
- ImageView imageView = new ImageView(mContext);
- if (i == 0) {
- imageView.setImageBitmap(mBtnSelect);
- rl.addView(imageView, layoutParams);
- } else {
- imageView.setImageBitmap(mBtnNormal);
- rl.addView(imageView, layoutParams);
- }
- this.addView(rl, params);
- mImageViews.add(imageView);
- }
- }
在EmojiLayout中完成表情页面的布局操作,包括表情页初始化,页面指示器等的初始化等等
- private ViewPager mViewPager;
- private IndicatorView mIndicatorView;
- private List<EmojiBean> mEmojiBeans;
- private List<View> mViewPageItems;
- private static final int COLUMNS = 7;
- private static final int ROWS = 3;
- private OnEmojiSelectListener mSelectListener;
- private void initView(){
- // 根据表情数量计算表情页数
- int pagerCount = getPagerCount(mEmojiBeans.size());
- // 页面指示器初始化
- mIndicatorView.init(pagerCount);
- // 表情页初始化
- mViewPageItems = new ArrayList<>();
- for (int i = 0;i<pagerCount;i++){
- mViewPageItems.add(createViewPage(i * COLUMNS * ROWS));
- }
- ViewPageAdapter adapter = new ViewPageAdapter(mViewPageItems);
- mViewPager.setAdapter(adapter);
- // 根据页面切换,更新指示器
- mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- int oldPosition = 0;
- @Override
- public void onPageScrolled(int position, float positionOffset,
- int positionOffsetPixels) {
- }
- @Override
- public void onPageSelected(int position) {
- mIndicatorView.playBy(oldPosition,position);
- oldPosition = position;
- }
- @Override
- public void onPageScrollStateChanged(int state) {
- }
- });
- }
创造表情页面的方法,使用GridView宫格布局,三行七列排布
- private View createViewPage(int offset){
- View view = LayoutInflater.from(getContext())
- .inflate(R.layout.layout_grid_view, null, false);
- GridView gridView = (GridView) view.findViewById(R.id.grid_view);
- int toIndex = offset + ROWS * COLUMNS;
- if (toIndex > mEmojiBeans.size() - 1) {
- toIndex = mEmojiBeans.size() - 1;
- }
- final List<EmojiBean> currentList = mEmojiBeans.subList(offset, toIndex);
- gridView.setAdapter(new GridViewAdapter(getContext(),currentList));
- gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- if (mSelectListener != null){
- if (position == parent.getAdapter().getCount() -1){
- mSelectListener.emojiDelete();
- }else {
- mSelectListener.emojiSelect(currentList.get(position));
- }
- }
- }
- });
- return gridView;
- }
张静:
本周开始写第二个自定义的Fragment, ContractFragment。对应界面中的“通讯录”。里面实现的功能有添加朋友,验证提醒,好友列表显示。
1. 设置加载的布局ID以及“通讯录”布局文件
- @Override
- public int setLayoutID() {
- return R.layout.fragment_contract;
- }
fragment_contract.xml
- <?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="match_parent"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:orientation="vertical"
- android:background="@color/interval_color">
- <RelativeLayout
- android:background="@color/white_color"
- android:id="@+id/layout_add_friend"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:paddingLeft="10dp"
- android:paddingRight="10dp">
- <ImageView
- android:id="@+id/iv_add_friend"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:padding="5dp"
- android:scaleType="fitXY"
- android:src="@mipmap/add_friend"/>
- <TextView
- android:layout_toRightOf="@+id/iv_add_friend"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:text="@string/add_friend"
- android:textSize="16sp"
- android:textColor="@color/app_black_color"
- android:layout_marginLeft="5dp"
- android:gravity="center"/>
- <View
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="0.8dp"
- android:background="@color/interval_color"/>
- </RelativeLayout>
- <RelativeLayout
- android:background="@color/white_color"
- android:id="@+id/layout_msg_notify"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:paddingLeft="10dp"
- android:paddingRight="10dp">
- <ImageView
- android:id="@+id/iv_msg_notify"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:padding="5dp"
- android:scaleType="fitXY"
- android:src="@mipmap/msg_notify"/>
- <TextView
- android:id="@+id/tv_alarm"
- android:layout_toRightOf="@+id/iv_msg_notify"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:text="@string/msg_notify"
- android:textSize="16sp"
- android:textColor="@color/app_black_color"
- android:layout_marginLeft="5dp"
- android:gravity="center"/>
- <View
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="0.8dp"
- android:background="@color/interval_color"/>
- </RelativeLayout>
- <android.support.v7.widget.RecyclerView
- android:layout_marginTop="10dp"
- android:background="@color/white_color"
- android:id="@+id/rcv_friend"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:paddingLeft="10dp"
- android:paddingRight="10dp"/>
- </LinearLayout>
2.初始化
验证提醒下方的空白处即好友列表,列表的每一项显示该好友头像和昵称(bindView)
点击某一项(setItemClickListener)会跳转进入该好友信息(FriendInfoActivity)
设置好友列表更新监听,加载好友列表(loadFriendList)
- @Override
- public void initView(View rootView) {
- ButterKnife.bind(this, rootView);
- mFriendList = new ArrayList<>();
- mViewAdapter = new RecycleViewAdapter<NimUserInfo>(getContext(), mFriendList) {
- @Override
- public int setItemLayoutId(int position) {
- return R.layout.item_friend;
- }
- @Override
- public void bindView(RViewHolder holder, int position) {
- NimUserInfo item = mFriendList.get(position);
- holder.setImageByUrl(getContext(), R.id.iv_head_picture,
- item.getAvatar(), R.mipmap.bg_img_defalut);
- holder.setText(R.id.tv_friend_nick, item.getName());
- }
- };
- mViewAdapter.setItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(RViewHolder holder, int position) {
- Intent intent = new Intent(getContext(), FriendInfoActivity.class);//创建intent对象,参数分别为上下文,要跳转的Activity类(朋友详细资料)
- //将要传递的值附加到Intent对象
- intent.putExtra("NimUserInfo", mFriendList.get(position)); //(键, 值)
- intent.putExtra("FLAG", FriendInfoActivity.FLAG_SHOW_FRIEND);
- //启动该Intent对象,实现跳转
- startActivity(intent);
- }
- });
- mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
- mRecyclerView.setAdapter(mViewAdapter);
- NimFriendHandler.getInstance().setUpdateListener(new OnFriendUpdateListener() {
- @Override
- public void friendUpdate() {
- loadFriendList();
- }
- });
- loadFriendList();
- }
3. FriendInfoActivity.java 好友信息(当点击好友列表一项时,进入对应的好友信息)(initView中用到)
(1)会显示头像,app名字(聊天工具),账号
可选择添加到通讯录,发送信息,视频聊天
(2)根据预先设置的FLAG选择所要显示的下方TextView
a. flag == FLAG_ADD_FRIEND
只显示“添加到通讯录”
b. flag == FLAG_SHOW_FRIEND
显示“发送信息”,“视频聊天”
c. flag == FLAG_PURE_SHOW_FRIEND
都不显示
initView中选择b
(3) 若点击了“添加到通讯录”,跳转到RequestFriendActivity
(4) 若点击了“发送信息”,跳转到P2PChatActivity
(5)可选择回退
- package com.ezreal.ezchat.activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.support.annotation.Nullable;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.TextView;
- import com.ezreal.ezchat.R;
- import com.joooonho.SelectableRoundedImageView;
- import com.netease.nimlib.sdk.uinfo.constant.GenderEnum;
- import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
- import com.ezreal.ezchat.commonlibrary.utils.ImageUtils;
- import java.util.Map;
- import butterknife.BindView;
- import butterknife.ButterKnife;
- import butterknife.OnClick;
- /**
- * Created by 张静
- */
- public class FriendInfoActivity extends BaseActivity {
- public static final int FLAG_ADD_FRIEND = 10001;
- public static final int FLAG_SHOW_FRIEND = 10002;
- public static final int FLAG_PURE_SHOW_FRIEND=10003;
- @BindView(R.id.iv_head_picture)
- SelectableRoundedImageView mHeadImg;
- @BindView(R.id.iv_person_sex)
- ImageView mIvPersonSex;
- @BindView(R.id.tv_remark)
- TextView mTvRemark;
- @BindView(R.id.tv_account)
- TextView mTvAccount;
- @BindView(R.id.tv_nike)
- TextView mTvNike;
- @BindView(R.id.tv_add_to_contract)
- TextView mTvAdd2Contract;
- @BindView(R.id.tv_start_chat)
- TextView mTvStartChat;
- @BindView(R.id.tv_video_chat)
- TextView mTvVideoChat;
- private NimUserInfo mNimUserInfo;
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setStatusBarColor(R.color.app_blue_color);
- setContentView(R.layout.activity_friend_info);
- setTitleBar("详细资料",true,true);
- ButterKnife.bind(this);
- bindViewByIntent();
- }
- private void bindViewByIntent(){
- Intent intent = getIntent();
- int flag = intent.getIntExtra("FLAG", FLAG_ADD_FRIEND);
- if ( flag == FLAG_ADD_FRIEND){
- mTvAdd2Contract.setVisibility(View.VISIBLE);
- mTvStartChat.setVisibility(View.GONE);
- mTvVideoChat.setVisibility(View.GONE);
- }else if (flag == FLAG_SHOW_FRIEND){
- mTvAdd2Contract.setVisibility(View.GONE);
- mTvStartChat.setVisibility(View.VISIBLE);
- mTvVideoChat.setVisibility(View.VISIBLE);
- }else if(flag==FLAG_PURE_SHOW_FRIEND){
- mTvAdd2Contract.setVisibility(View.GONE);
- mTvStartChat.setVisibility(View.GONE);
- mTvVideoChat.setVisibility(View.GONE);
- }
- mNimUserInfo = (NimUserInfo) intent.getSerializableExtra("NimUserInfo");
- if (mNimUserInfo != null){
- ImageUtils.setImageByUrl(this,mHeadImg,mNimUserInfo.getAvatar(),R.mipmap.app_logo_main);
- if (mNimUserInfo.getGenderEnum() == GenderEnum.FEMALE){
- mIvPersonSex.setImageResource(R.mipmap.ic_woman);
- }else if (mNimUserInfo.getGenderEnum() == GenderEnum.MALE){
- mIvPersonSex.setImageResource(R.mipmap.ic_man);
- }
- mTvAccount.setText(mNimUserInfo.getAccount());
- mTvNike.setText(mNimUserInfo.getName());
- String remark = mNimUserInfo.getName();
- Map<String, Object> extensionMap = mNimUserInfo.getExtensionMap();
- if (extensionMap != null && extensionMap.containsKey("remark")){
- remark = extensionMap.get("remark").toString();
- }
- mTvRemark.setText(remark);
- }
- }
- /**
- * 设置备注信息
- */
- @OnClick(R.id.tv_set_remark)
- public void setRemark(){
- }
- /**
- * 添加好友
- */
- @OnClick(R.id.tv_add_to_contract)
- public void add2Contract(){
- Intent intent = new Intent(this,RequestFriendActivity.class);
- intent.putExtra("account",mNimUserInfo.getAccount());
- startActivity(intent);
- }
- /**
- * 跳转至聊天界面
- */
- @OnClick(R.id.tv_start_chat)
- public void startChat(){
- Intent intent = new Intent(this,P2PChatActivity.class);
- intent.putExtra("NimUserInfo",mNimUserInfo);
- startActivity(intent);
- }
- /**
- * 跳转到视频聊天界面
- */
- @OnClick(R.id.tv_video_chat)
- public void startVideoChat(){
- }
- @OnClick(R.id.iv_back_btn)
- public void backClick(){
- this.finish();
- }
activity_friend_info.xml
- <?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="match_parent"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:orientation="vertical"
- android:fitsSystemWindows="true">
- <include layout="@layout/title_layout"/>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:background="@color/interval_color">
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="100dp"
- android:layout_marginTop="10dp"
- android:background="@color/white_color">
- <com.joooonho.SelectableRoundedImageView
- android:id="@+id/iv_head_picture"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:layout_margin="10dp"
- app:sriv_oval="true"
- android:scaleType="fitXY"
- android:src="@mipmap/app_logo_main"/>
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_toRightOf="@id/iv_head_picture"
- android:gravity="center_vertical"
- android:orientation="vertical">
- <TextView
- android:id="@+id/tv_remark"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_name"
- android:textSize="16sp"
- android:textColor="@color/app_black_color"/>
- <ImageView
- android:id="@+id/iv_person_sex"
- android:layout_toRightOf="@+id/tv_remark"
- android:layout_width="15dp"
- android:layout_height="15dp"
- android:layout_marginLeft="10dp"
- android:src="@mipmap/ic_man"/>
- <TextView
- android:id="@+id/tv_tip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/tv_remark"
- android:layout_marginTop="10dp"
- android:text="@string/account_tip"
- android:textSize="16sp"
- android:textColor="@color/app_black_color"/>
- <TextView
- android:id="@+id/tv_account"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/tv_remark"
- android:layout_marginTop="10dp"
- android:layout_toRightOf="@+id/tv_tip"
- android:text="Ezreal-520"
- android:textSize="16sp"
- android:textColor="@color/app_black_color"/>
- <TextView
- android:id="@+id/tv_tip_nike"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/tv_tip"
- android:layout_marginTop="10dp"
- android:text="@string/nike_tip"
- android:textSize="16sp"
- android:textColor="@color/app_black_color"/>
- <TextView
- android:id="@+id/tv_nike"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/tv_account"
- android:layout_marginTop="10dp"
- android:textSize="16sp"
- android:layout_toRightOf="@+id/tv_tip_nike"
- android:text="Fate"
- android:textColor="@color/app_black_color"/>
- </RelativeLayout>
- </RelativeLayout>
- <View
- android:layout_width="match_parent"
- android:layout_height="10dp"/>
- <TextView
- android:id="@+id/tv_set_remark"
- android:gravity="center"
- android:textSize="18sp"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:background="@color/white_color"
- android:textColor="@color/app_black_color"
- android:text="@string/set_remark_info"
- android:visibility="visible"/>
- <View
- android:layout_width="match_parent"
- android:layout_height="40dp"/>
- <TextView
- android:id="@+id/tv_start_chat"
- android:gravity="center"
- android:textSize="18sp"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:background="@color/app_blue_color"
- android:textColor="@color/white_color"
- android:text="@string/send_message"
- android:visibility="visible"/>
- <TextView
- android:id="@+id/tv_video_chat"
- android:layout_marginTop="10dp"
- android:gravity="center"
- android:textSize="18sp"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:background="@color/white_color"
- android:textColor="@color/app_blue_color"
- android:text="@string/video_chat"
- android:visibility="gone"/>
- <TextView
- android:id="@+id/tv_add_to_contract"
- android:layout_marginTop="10dp"
- android:gravity="center"
- android:textSize="18sp"
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:background="@color/app_blue_color"
- android:textColor="@color/white_color"
- android:text="@string/add_to_contract"/>
- </LinearLayout>
- </LinearLayout>