李晨晨:
本次我主要實現了上次圖片選擇界面中的圖片預覽activity。
1.首先在上次的PhotoSelectActivity中加入帶result請求的頁面跳轉,以及相應的result處理:
- /**
- * 單擊單張圖片時,調整到預覽頁面顯示該圖
- */
- private void previewByItem(){
- Intent intent = new Intent(this,ImagePreviewActivity.class);
- intent.putExtra("FLAG", ImagePreviewActivity.FLAG_SHOW_ITEM);
- intent.putExtra("IMAGE_ITEM",mShowItem);
- startActivityForResult(intent,REQUEST_SHOW_ITEM);
- }
-
- /**
- * 單擊「預覽」按鈕時,跳轉到預覽頁面顯示所有已選中的圖片
- */
- private void previewByBtn(){
- Intent intent = new Intent(this,ImagePreviewActivity.class);
- intent.putExtra("FLAG", ImagePreviewActivity.FLAG_SHOW_LIST);
- intent.putExtra("IMAGE_LIST", (Serializable) mSelectedImages);
- startActivityForResult(intent,REQUEST_SHOW_LIST);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- // 預覽界面點擊了「發送」按鈕
- if (resultCode == RESULT_OK){
- if (requestCode == REQUEST_SHOW_ITEM){
- if (mShowItem != null){
- mSelectedImages.clear();
- mSelectedImages.add(mShowItem);
- sendImage();
- }
- }else if (requestCode == REQUEST_SHOW_LIST){
- sendImage();
- }
- }
- }
2.ImagePreviewActivity中,主要分爲控件id綁定,從上一個intent中獲得要顯示的圖片,顯示圖片,以及自定義的PagerAdapter和IndicatorView。
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_image_preview);
- findView();
- getImageFromIntent();
- showImage();
- }
相應的佈局:
activity_image_preview.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"
- android:orientation="vertical">
-
- <include layout="@layout/layout_title"/>
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1">
-
- <android.support.v4.view.ViewPager
- android:id="@+id/view_page"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-
- <com.ezreal.ezchat.photoselector.IndicatorView
- android:id="@+id/indicator_view"
- android:layout_width="match_parent"
- android:layout_height="25dp"
- android:layout_alignParentBottom="true"
- android:layout_marginBottom="5dp"
- android:gravity="center"/>
- </RelativeLayout>
-
- </LinearLayout>
item_image_pre.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/layout_img"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <com.bm.library.PhotoView
- android:id="@+id/iv_img"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/black"/>
-
- </RelativeLayout>
2.findView方法:其中爲返回鍵和發送鍵設置了OnClickListener。
- private void findView() {
- mTvTitle = (TextView) findViewById(R.id.tv_title);
- mTvTitle.setText("預覽");
-
- mIvBack = (ImageView) findViewById(R.id.iv_back);
- mIvBack.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ImagePreviewActivity.this.setResult(RESULT_CANCELED);
- finish();
- }
- });
-
- mTvSend = (TextView) findViewById(R.id.tv_send);
- mTvSend.setText("發送");
- mTvSend.setTextColor(Color.WHITE);
- mTvSend.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- ImagePreviewActivity.this.setResult(RESULT_OK);
- finish();
- }
- });
-
- mIndicatorView = (IndicatorView) findViewById(R.id.indicator_view);
- mViewPager = (ViewPager) findViewById(R.id.view_page);
- }
3.getImageFromIntent方法:根據上一個activity不同的flag設置不同的響應。
- private void getImageFromIntent() {
- mImageBeans = new ArrayList<>();
- int flag = getIntent().getIntExtra("FLAG", FLAG_SHOW_ITEM);
- if (flag == FLAG_SHOW_ITEM) {
- ImageBean image = (ImageBean) getIntent().getSerializableExtra("IMAGE_ITEM");
- if (image != null) {
- mImageBeans.add(image);
- }
- } else if (flag == FLAG_SHOW_LIST) {
- List<ImageBean> list = (List<ImageBean>) getIntent().getSerializableExtra("IMAGE_LIST");
- if (list != null) {
- mImageBeans.addAll(list);
- }
- }
- createViews();
- }
其中用到的createViews方法:
- private void createViews() {
- mViews = new ArrayList<>();
- for (int i = 0; i < mImageBeans.size(); i++) {
- View view = LayoutInflater.from(this).inflate(R.layout.item_image_pre,
- null, false);
- PhotoView photoView = (PhotoView) view.findViewById(R.id.iv_img);
- photoView.setMaxScale(4);
- photoView.enable();
- Glide.with(ImagePreviewActivity.this)
- .load(mImageBeans.get(i).getPath()).diskCacheStrategy(DiskCacheStrategy.ALL)
- .error(R.drawable.bg_img_defalut)
- .into(photoView);
- mViews.add(view);
- }
- mIndicatorView.init(mViews.size());
- }
4.showImage方法:
- private void showImage() {
- mPageAdapter = new ViewPageAdapter(mViews);
- mViewPager.setAdapter(mPageAdapter);
- mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
-
- private int mOldPosition = 0;
-
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
-
- }
-
- @Override
- public void onPageSelected(int position) {
- mIndicatorView.playBy(mOldPosition, position);
- mOldPosition = position;
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
-
- }
- });
- }
5.用到的自定義PagerAdapter-ViewPageAdapter
- private class ViewPageAdapter extends PagerAdapter {
-
- private List<View> mViews;
-
- public ViewPageAdapter(List<View> views) {
- mViews = views;
- }
-
- @Override
- public int getCount() {
- return mViews != null ? mViews.size() : 0;
- }
-
- @Override
- public Object instantiateItem(ViewGroup container, int position) {
- container.addView(mViews.get(position));
- return mViews.get(position);
- }
-
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView(mViews.get(position));
- }
-
- @Override
- public boolean isViewFromObject(View view, Object object) {
- return view == object;
- }
- }
6.IndicatorView選擇指示器:主要是滑動圖片時,相應的下面的小圓點的動畫。
- public class IndicatorView extends LinearLayout {
-
- private Context mContext;
- private ArrayList<ImageView> mImageViews;
- private Bitmap mBtnSelect;
- private Bitmap mBtnNormal;
- private int mMaxHeight;
- private int mMaxWidth;
- private AnimatorSet mPlayToAnimatorSet;
- private AnimatorSet mPlayByInAnimatorSet;
- private AnimatorSet mPlayByOutAnimatorSet;
-
- public IndicatorView(Context context) {
- this(context, null);
- }
-
- public IndicatorView(Context context, AttributeSet attrs) {
- super(context, attrs);
- this.mContext = context;
- this.setOrientation(HORIZONTAL);
- mMaxWidth = mMaxHeight = dip2px(16);
- mBtnSelect = BitmapFactory.decodeResource(getResources(), R.drawable.indicator_point_select);
- mBtnNormal = BitmapFactory.decodeResource(getResources(), R.drawable.indicator_point_nomal);
- }
-
- 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);
- }
- }
-
- public void playBy(int startPosition, int nextPosition) {
-
- boolean isShowInAnimOnly = false;
- if (startPosition < 0 || nextPosition < 0 || nextPosition == startPosition) {
- startPosition = nextPosition = 0;
- }
-
- if (startPosition < 0) {
- isShowInAnimOnly = true;
- startPosition = nextPosition = 0;
- }
-
- final ImageView imageViewStrat = mImageViews.get(startPosition);
- final ImageView imageViewNext = mImageViews.get(nextPosition);
-
- ObjectAnimator anim1 = ObjectAnimator.ofFloat(imageViewStrat,
- "scaleX", 1.0f, 0.25f);
- ObjectAnimator anim2 = ObjectAnimator.ofFloat(imageViewStrat,
- "scaleY", 1.0f, 0.25f);
-
- if (mPlayByOutAnimatorSet != null && mPlayByOutAnimatorSet.isRunning()) {
- mPlayByOutAnimatorSet.cancel();
- mPlayByOutAnimatorSet = null;
- }
- mPlayByOutAnimatorSet = new AnimatorSet();
- mPlayByOutAnimatorSet.play(anim1).with(anim2);
- mPlayByOutAnimatorSet.setDuration(100);
-
- ObjectAnimator animIn1 = ObjectAnimator.ofFloat(imageViewNext,
- "scaleX", 0.25f, 1.0f);
- ObjectAnimator animIn2 = ObjectAnimator.ofFloat(imageViewNext,
- "scaleY", 0.25f, 1.0f);
-
- if (mPlayByInAnimatorSet != null && mPlayByInAnimatorSet.isRunning()) {
- mPlayByInAnimatorSet.cancel();
- mPlayByInAnimatorSet = null;
- }
- mPlayByInAnimatorSet = new AnimatorSet();
- mPlayByInAnimatorSet.play(animIn1).with(animIn2);
- mPlayByInAnimatorSet.setDuration(100);
-
- if (isShowInAnimOnly) {
- mPlayByInAnimatorSet.start();
- return;
- }
-
- anim1.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- imageViewStrat.setImageBitmap(mBtnNormal);
- ObjectAnimator animFil1l = ObjectAnimator.ofFloat(imageViewStrat,
- "scaleX", 1.0f);
- ObjectAnimator animFill2 = ObjectAnimator.ofFloat(imageViewStrat,
- "scaleY", 1.0f);
- AnimatorSet mFillAnimatorSet = new AnimatorSet();
- mFillAnimatorSet.play(animFil1l).with(animFill2);
- mFillAnimatorSet.start();
- imageViewNext.setImageBitmap(mBtnSelect);
- mPlayByInAnimatorSet.start();
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- });
- mPlayByOutAnimatorSet.start();
- }
-
- private int dip2px(float dipValue) {
- final float scale = getContext().getResources().getDisplayMetrics().density;
- return (int) (dipValue * scale + 0.5f);
- }
- }
最終效果:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
下面的四個小點就是選擇指示器,代表預覽界面有幾張圖片。哪一個小點暗一點就代表顯示的是那一張。
仝心:
這次的工作在上次的基礎上完成錄音發送功能。
自定義AudioRecordButton類繼承自Button,用於實現聊天時的錄音和發送語音及其他一些相關功能。
構造方法,設置按鈕樣式以及提示用戶可以按住按鈕說話
- public AudioRecordButton(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- // 初始化按鈕樣式
- setBackgroundResource(R.drawable.record_button_normal);
- setText(getResources().getString(R.string.press_record));//按住 說話
- }
初始化按鈕,並設置長按按鈕的事件監聽器。
- public void init(String audioSaveDir) {
- mAudioSaveDir = audioSaveDir;
- // 初始化 dialog 管理器
- mDialogManager = new RecordDialogManager(getContext());
- // 獲取音頻管理,以申請音頻焦點
- mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
- // 初始化錄音管理器
- mAudioRecordManager = AudioRecordManager.getInstance(mAudioSaveDir);
-
- mAudioRecordManager.setAudioStateListener(this);
-
- // 設置按鈕長按事件監聽,只有觸發長按纔開始準備錄音
- setOnLongClickListener(new OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- // 獲取焦點
- int focus = mAudioManager.requestAudioFocus(null,
- AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
- if (focus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED){
- isReady = true;
- mAudioRecordManager.prepareAudio();
- }else if (focus == AudioManager.AUDIOFOCUS_REQUEST_FAILED){
- if (mRecordingListener != null) {
- mRecordingListener.recordError("AUDIO_FOCUS_REQUEST_FAILED");
- }
- }
- return true;
- }
- });
- hasInit = true;
- }
子線程runnable,每間隔0.1秒獲取音量大小,並記錄錄音時間
- private Runnable mGetVoiceLevelRunnable = new Runnable() {
- @Override
- public void run() {
- while (isRecording) {
- try {
- Thread.sleep(100);
- mRecordTime += 100;
- mHandler.sendEmptyMessage(MSG_VOICE_CHANGE);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- };
通過Handler關聯子線程,通過Handler將Message和Runnable對象發送到該Handler所關聯線程的MessageQueue(消息隊列)中,然後該消息隊列一直在循環拿出一個Message,對其進行處理,處理完之後拿出下一個Message,繼續進行處理,周而復始。
- @SuppressLint("HandlerLeak")
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- switch (msg.what) {
- case MSG_AUDIO_PREPARED:
- // 錄音管理器 prepare 成功,開始錄音並顯示dialog
- // 啓動線程記錄時間並獲取音量變化
- isRecording = true;
- mDialogManager.showDialogRecord();
- // 啓動線程,每隔0.1秒獲取音量大小
- new Thread(mGetVoiceLevelRunnable).start();
- break;
- case MSG_VOICE_CHANGE:
- mDialogManager.updateVoiceLevel(mAudioRecordManager.getVoiceLevel(7));
- break;
- case MSG_DIALOG_DISMISS:
- mDialogManager.dismissDialog();
- break;
- }
- }
- };
改變錄音提示狀態,包括「按住 說話」、「鬆開 發送」、「鬆開手指 取消發送」
- private void changeState(int state) {
- if (mCurrentState != state) {
- mCurrentState = state;
- if (state == STATE_NORMAL) {
- setText(getResources().getString(R.string.press_record));
- setBackgroundResource(R.drawable.record_button_normal);
- } else if (state == STATE_RECORDING) {
- setText(getResources().getString(R.string.release_end));
- setBackgroundResource(R.drawable.record_button_recoding);
- if (isRecording) {
- mDialogManager.showRecording();
- }
- } else if (state == STATE_WANT_CANCEL) {
- setText(getResources().getString(R.string.release_cancel));
- setBackgroundResource(R.drawable.record_button_recoding);
- if (isRecording) {
- mDialogManager.showDialogWantCancel();
- }
- }
- }
- }
判斷是否要取消語音發送,通過判斷觸控點的x、y座標變化來判斷用戶行爲。
- private boolean isWantToCancel(int x, int y) {
- return x < 0 || x > getWidth()
- || y < -CANCEL_HEIGHT || y > getHeight() + CANCEL_HEIGHT;
- }
釋放資源,釋放音頻焦點
- private void reset() {
- isReady = false;
- isRecording = false;
- mRecordTime = 0;
- changeState(STATE_NORMAL);
-
- // 釋放焦點
- if (mAudioManager != null){
- mAudioManager.abandonAudioFocus(null);
- }
- }
然後在上週的文本輸入框中添加發送錄音的功能
- // 錄音按鈕初始化和錄音監聽
- mBtnAudioRecord.init(Constant.APP_CACHE_AUDIO);
- mBtnAudioRecord.setRecordingListener(new AudioRecordButton.OnRecordingListener() {
- @Override
- public void recordFinish(String audioFilePath, long recordTime) {
- if (mLayoutListener != null) {
- mLayoutListener.audioRecordFinish(audioFilePath, recordTime);
- }
- }
-
- @Override
- public void recordError(String message) {
- if (mLayoutListener != null) {
- mLayoutListener.audioRecordError(message);
- }
- }
- });
張靜:
接下來完成「驗證提醒」後會跳轉進入的界面以及相關功能實現
一. activity_check_notify.xml (進入驗證提醒後總體界面的佈局)
- <?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"
- android:fitsSystemWindows="true">
-
- <include layout="@layout/title_layout"/>
-
-
- <android.support.v7.widget.RecyclerView
- android:background="@color/interval_color"
- android:id="@+id/rcv_notify_list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-
- </LinearLayout>
![](http://static.javashuo.com/static/loading.gif)
二. CheckNotifyListActivity(處理驗證消息)
1.初始化
(1)(2)爲適配器方法
(1)設置每一項的佈局
- @Override
- public int setItemLayoutId(int position) {
- return R.layout.item_check_notify;
- }
item_check_notify.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:background="@color/white_color"
- android:layout_height="wrap_content"
- android:gravity="center_vertical">
-
- <LinearLayout
- android:id="@+id/layout_notify"
- android:layout_width="match_parent"
- android:layout_height="65dp"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:paddingTop="5dp"
- android:layout_marginLeft="10dp"
- android:layout_marginRight="10dp">
-
- <com.joooonho.SelectableRoundedImageView
- android:padding="5dp"
- android:id="@+id/iv_head_picture"
- android:layout_width="60dp"
- android:layout_height="match_parent"
- android:scaleType="fitXY"
- app:sriv_oval="true"/>
-
- <LinearLayout
- android:id="@+id/msg_detail"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_marginLeft="5dp"
- android:layout_weight="1"
- android:gravity="center_vertical"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/tv_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLines="1"
- android:text="@string/app_name"
- android:textColor="@color/app_black_color"/>
-
- <TextView
- android:id="@+id/tv_content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dp"
- android:maxLines="1"
- android:text="@string/test_msg"
- android:textColor="@color/default_text_color"/>
- </LinearLayout>
-
-
- <TextView
- android:id="@+id/tv_do_agree"
- android:layout_marginLeft="5dp"
- android:layout_width="50dp"
- android:layout_height="30dp"
- android:gravity="center"
- android:background="@drawable/tv_btn_round_green"
- android:text="@string/do_agree"
- android:textColor="@color/app_green_color"
- android:visibility="visible"/>
-
- <TextView
- android:id="@+id/tv_do_refuse"
- android:layout_marginLeft="10dp"
- android:layout_width="50dp"
- android:layout_height="30dp"
- android:background="@drawable/tv_btn_round_red"
- android:gravity="center"
- android:text="@string/do_refuse"
- android:textColor="@color/app_red_color"
- android:visibility="visible"/>
-
- <TextView
- android:id="@+id/tv_status"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="5dp"
- android:layout_marginRight="10dp"
- android:text="@string/have_agree"
- android:visibility="gone"
- android:textColor="@color/app_black_color"/>
- </LinearLayout>
-
- <View
- android:layout_marginTop="5dp"
- android:layout_below="@+id/layout_notify"
- android:layout_width="match_parent"
- android:layout_height="0.8dp"
- android:background="@color/interval_color"/>
- </RelativeLayout>
![](http://static.javashuo.com/static/loading.gif)
(2)綁定控件
每一項會顯示該用戶頭像和用戶名
同時,設有兩個個TextView爲「同意」和「拒絕」以及一個表示信息處理狀態的TextView(會顯示「已拒絕」或「已同意」):
a. 若獲取的系統通知的處理狀態爲「declined」(已拒絕),兩個TextView「同意」「拒絕」均不顯示,顯示「已拒絕」
b. 若獲取的系統通知的處理狀態爲「passed」(已通過驗證),兩個TextView「同意」「拒絕」均不顯示,顯示「已同意」
c.否則,同時顯示「同意」,「拒絕」。(默認情況下)
爲兩個TextView「同意」和「拒絕」分別設置onClickListener
- @Override
- public void bindView(RViewHolder holder, final int position) {
- final AddFriendNotify item = mNotifyInfoList.get(position);
- SystemMessage message = item.getMessage();
- NimUserInfo userInfo = item.getUserInfo();
- if (userInfo != null) {
- holder.setImageByUrl(CheckNotifyListActivity.this, R.id.iv_head_picture,
- userInfo.getAvatar(), R.mipmap.bg_img_defalut);
- holder.setText(R.id.tv_name, userInfo.getName());
- } else {
- holder.setImageResource(R.id.iv_head_picture, R.mipmap.bg_img_defalut);
- holder.setText(R.id.tv_name, message.getFromAccount());
- }
-
- holder.setText(R.id.tv_content, message.getContent());
-
- TextView tv_status = holder.getTextView(R.id.tv_status);
- TextView tv_agree = holder.getTextView(R.id.tv_do_agree);
- TextView tv_refuse = holder.getTextView(R.id.tv_do_refuse);
- if (message.getStatus() == SystemMessageStatus.declined) {
- tv_agree.setVisibility(View.GONE);
- tv_refuse.setVisibility(View.GONE);
- tv_status.setText("已拒絕");
- tv_status.setVisibility(View.VISIBLE);
- } else if (message.getStatus() == SystemMessageStatus.passed) {
- tv_agree.setVisibility(View.GONE);
- tv_refuse.setVisibility(View.GONE);
- tv_status.setText("已同意");
- tv_status.setVisibility(View.VISIBLE);
- } else if (message.getStatus() == SystemMessageStatus.init) {
- tv_status.setText("");
- tv_status.setVisibility(View.GONE);
- tv_agree.setVisibility(View.VISIBLE);
- tv_refuse.setVisibility(View.VISIBLE);
- }
- tv_agree.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dealRequest(item.getMessage().getFromAccount(), position, true);
- }
- });
-
- tv_refuse.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dealRequest(item.getMessage().getFromAccount(), position, false);
- }
- });
- }
(3)對驗證提醒界面中的某一項,若長按,可選擇是否刪除該條信息
- mAdapter.setItemLongClickListener(new OnItemLongClickListener() {
- @Override
- public void onItemLongClick(RViewHolder holder, int position) {
- ignoreRequest(position);
- }
- });
(4)對驗證提醒界面中的某一項,若點擊,可查看該用戶信息
- mAdapter.setItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(RViewHolder holder, int position) {
- showAccountInfo(position);
- }
- });
(5)初始化好友添加通知監聽,收到信息後刷新頁面
- NimSysMsgHandler.getInstance().setMessageListener(new SystemMessageListener() {
- @Override
- public void addFriendNotify() {
- loadAddFriendNotify();
- }
- });
(6)完整初始化過程
- private void init() {
- mNotifyInfoList = new ArrayList<>();
- mAdapter = new RecycleViewAdapter<AddFriendNotify>(this, mNotifyInfoList) {
- @Override
- public int setItemLayoutId(int position) {
- return R.layout.item_check_notify;
- }
-
- @Override
- public void bindView(RViewHolder holder, final int position) {
- final AddFriendNotify item = mNotifyInfoList.get(position);
- SystemMessage message = item.getMessage();
- NimUserInfo userInfo = item.getUserInfo();
- if (userInfo != null) {
- holder.setImageByUrl(CheckNotifyListActivity.this, R.id.iv_head_picture,
- userInfo.getAvatar(), R.mipmap.bg_img_defalut);
- holder.setText(R.id.tv_name, userInfo.getName());
- } else {
- holder.setImageResource(R.id.iv_head_picture, R.mipmap.bg_img_defalut);
- holder.setText(R.id.tv_name, message.getFromAccount());
- }
-
- holder.setText(R.id.tv_content, message.getContent());
-
- TextView tv_status = holder.getTextView(R.id.tv_status);
- TextView tv_agree = holder.getTextView(R.id.tv_do_agree);
- TextView tv_refuse = holder.getTextView(R.id.tv_do_refuse);
- if (message.getStatus() == SystemMessageStatus.declined) {
- tv_agree.setVisibility(View.GONE);
- tv_refuse.setVisibility(View.GONE);
- tv_status.setText("已拒絕");
- tv_status.setVisibility(View.VISIBLE);
- } else if (message.getStatus() == SystemMessageStatus.passed) {
- tv_agree.setVisibility(View.GONE);
- tv_refuse.setVisibility(View.GONE);
- tv_status.setText("已同意");
- tv_status.setVisibility(View.VISIBLE);
- } else if (message.getStatus() == SystemMessageStatus.init) {
- tv_status.setText("");
- tv_status.setVisibility(View.GONE);
- tv_agree.setVisibility(View.VISIBLE);
- tv_refuse.setVisibility(View.VISIBLE);
- }
- tv_agree.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dealRequest(item.getMessage().getFromAccount(), position, true);
- }
- });
-
- tv_refuse.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dealRequest(item.getMessage().getFromAccount(), position, false);
- }
- });
- }
- };
- //若長按,可選擇是否刪除該條信息
- mAdapter.setItemLongClickListener(new OnItemLongClickListener() {
- @Override
- public void onItemLongClick(RViewHolder holder, int position) {
- ignoreRequest(position);
- }
- });
-
- //若點擊,可查看該用戶信息
- mAdapter.setItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(RViewHolder holder, int position) {
- showAccountInfo(position);
- }
- });
-
- mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
- mRecyclerView.setAdapter(mAdapter);
-
- // Tool Bar
- mIvBack.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
-
- // 初始化好友添加通知監聽,收到信息後刷新頁面
- NimSysMsgHandler.getInstance().setMessageListener(new SystemMessageListener() {
- @Override
- public void addFriendNotify() {
- loadAddFriendNotify();
- }
- });
-
- loadAddFriendNotify();
- }
2. 讀取好友添加通知數據(loadAddFriendNotify)
(1)獲取「添加朋友」消息列表
通過NimClient的getService接口獲取到SystemMessageService(系統通知消息接口)服務實例,調用querySystemMessageByTypeBlock方法根據類型查詢系統通知列表
(2)根據對方賬戶,獲取賬戶信息,構建顯示item數據
item數據在兩種情況下不顯示:
a. 若獲取到的系統通知的處理狀態爲ignored(已忽略)
b. 若獲取不到該條記錄的賬戶數據
其餘顯示的item設置信息,設置好友(通過NimFriendHandler的CheckIsMyFriend(檢查該賬戶是否爲我的好友)),設置信息,添加到通知列表
(3)刷新界面
(4)將「添加朋友」消息置爲已讀
- private void loadAddFriendNotify() {
- List<SystemMessageType> types = new ArrayList<>();
- types.add(SystemMessageType.AddFriend);
-
- // 獲取「添加朋友」消息列表
- List<SystemMessage> msgList = NIMClient.getService(SystemMessageService.class)
- .querySystemMessageByTypeBlock(types, 0, LOAD_MESSAGE_COUNT);
-
- // 根據對方賬戶,獲取賬戶信息,構建顯示 item 數據
- AddFriendNotify notify;
- List<AddFriendNotify> notifyInfoList = new ArrayList<>();
- for (SystemMessage message : msgList) {
- // 若用戶已選擇忽略這條消息,則跳過不顯示
- if (message.getStatus() == SystemMessageStatus.ignored) {
- continue;
- }
- NimUserInfo userInfo = NimUserHandler.getInstance().getUserInfo();
- //若獲取不到該條記錄的賬戶數據,也跳過不顯示
- if (userInfo == null) {
- return;
- }
-
- notify = new AddFriendNotify();
- notify.setMessage(message);
- notify.setMyFriend(NimFriendHandler.getInstance().CheckIsMyFriend(message.getFromAccount()));
- notify.setUserInfo(userInfo);
- notifyInfoList.add(notify);
- }
-
- // 刷新界面
- mNotifyInfoList.clear();
- mNotifyInfoList.addAll(notifyInfoList);
- mAdapter.notifyDataSetChanged();
-
- // 將「添加朋友」消息至爲已讀
- NIMClient.getService(SystemMessageService.class)
- .resetSystemMessageUnreadCountByType(types);
- }
3. 處理好友請求(dealRequest)
通過NimClient的getService接口獲取到FriendService(好友管理/好友關係/黑名單關係/消息提醒相關操作)服務實例,調用ackAddFriendRequest方法進行同意/拒絕好友請求
設置回調,三種情況
(1)成功(onSuccess)
a. 如果同意,則將系統消息狀態設置爲"passed"(已通過驗證)
b. 否則,將系統消息狀態設置爲"declined"(已拒絕)
通過NimClient的getService接口獲取到SystemMessageService(系統通知消息接口)服務實例調用setSystemMessageStatus
方法設置系統通知狀態(根據前面同意與否所決定的狀態設置)
(2)失敗(onFailed):顯示消息「處理失敗,code:xxx」
(3)出錯(onException):顯示消息「處理出錯:xxx」
- private void dealRequest(String account, int position, final boolean agree) {
- final SystemMessage message = mNotifyInfoList.get(position).getMessage();
- NIMClient.getService(FriendService.class)
- .ackAddFriendRequest(account, agree).setCallback(new RequestCallback<Void>() {
- @Override
- public void onSuccess(Void param) {
- SystemMessageStatus status;
- if (agree) {
- status = SystemMessageStatus.passed;
- } else {
- status = SystemMessageStatus.declined;
- }
- NIMClient.getService(SystemMessageService.class)
- .setSystemMessageStatus(message.getMessageId(), status);
- message.setStatus(status);
- mAdapter.notifyDataSetChanged();
- haveChange = true;
- }
-
- @Override
- public void onFailed(int code) {
- ToastUtils.showMessage(CheckNotifyListActivity.this, "處理失敗,code:" + code);
- }
-
- @Override
- public void onException(Throwable exception) {
- ToastUtils.showMessage(CheckNotifyListActivity.this, "處理出錯:" + exception.getMessage());
- }
- });
- }
4. 刪除並忽略該條記錄——對應於初始化中若長按某一項所進行的操作
利用AlertDialog:
(1)setMessege:設置對話框中的內容爲「是否刪除該條記錄?」
(2)setCancelable(true):設置當點對話框以外的地方,退出對話框
(3)setPositiveButton:確定刪除,通過NimClient的getService接口獲取到SystemMessageService()服務實例,調用setSystemMessageStatus方法設置狀態爲ignored
通知列表中刪除該條
退出對話框
(4)setNegativeButton:取消,退出對話框
- private void ignoreRequest(final int position) {
- new AlertDialog.Builder(this)
- .setMessage("是否刪除該條記錄?")
- .setCancelable(true)
- .setPositiveButton("確定", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SystemMessage message = mNotifyInfoList.get(position).getMessage();
- NIMClient.getService(SystemMessageService.class)
- .setSystemMessageStatus(message.getMessageId(),
- SystemMessageStatus.ignored);
- mNotifyInfoList.remove(position);
- mAdapter.notifyDataSetChanged();
- dialog.dismiss();
- }
- })
- .setNegativeButton("取消", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- }).show();
-
- }
5. 顯示賬號信息(showAccountInfo)——對應於初始化中若點擊,可查看該用戶信息
跳轉到FriendInfoActivity(之前博客已寫)
a. 若已經是朋友(flag == FLAG_SHOW_FRIEND),則FriendInfoActivity中可選擇「發送信息」,「視頻聊天」
b. 否則(flag == FLAG_ADD_FRIEND), 則FriendInfoActivity中只可選擇「添加到通訊錄」
- private void showAccountInfo(int position){
- AddFriendNotify notifyInfo = mNotifyInfoList.get(position);
- Intent intent = new Intent(this,FriendInfoActivity.class);
- intent.putExtra("NimUserInfo",notifyInfo.getUserInfo());
- if (notifyInfo.isMyFriend()){
- intent.putExtra("FLAG",FriendInfoActivity.FLAG_SHOW_FRIEND);
- }else {
- intent.putExtra("FLAG",FriendInfoActivity.FLAG_ADD_FRIEND);
- }
- startActivity(intent);
- }
附上完整CheckNotifyListActivity.java
- package com.ezreal.ezchat.activity;
-
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.os.Bundle;
- import android.support.annotation.Nullable;
- import android.support.v7.app.AlertDialog;
- import android.support.v7.widget.LinearLayoutManager;
- import android.support.v7.widget.RecyclerView;
- import android.view.View;
- import android.widget.TextView;
-
- import com.ezreal.ezchat.R;
- import com.ezreal.ezchat.bean.AddFriendNotify;
- import com.ezreal.ezchat.handler.NimFriendHandler;
- import com.ezreal.ezchat.handler.NimUserHandler;
- import com.ezreal.ezchat.handler.NimSysMsgHandler;
- import com.ezreal.ezchat.handler.NimSysMsgHandler.SystemMessageListener;
- import com.netease.nimlib.sdk.NIMClient;
- import com.netease.nimlib.sdk.RequestCallback;
- import com.netease.nimlib.sdk.friend.FriendService;
- import com.netease.nimlib.sdk.msg.SystemMessageService;
- import com.netease.nimlib.sdk.msg.constant.SystemMessageStatus;
- import com.netease.nimlib.sdk.msg.constant.SystemMessageType;
- import com.netease.nimlib.sdk.msg.model.SystemMessage;
- import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
- import com.ezreal.ezchat.commonlibrary.adapter.OnItemClickListener;
- import com.ezreal.ezchat.commonlibrary.adapter.OnItemLongClickListener;
- import com.ezreal.ezchat.commonlibrary.adapter.RViewHolder;
- import com.ezreal.ezchat.commonlibrary.adapter.RecycleViewAdapter;
- import com.ezreal.ezchat.commonlibrary.utils.ToastUtils;
-
- import java.util.ArrayList;
- import java.util.List;
-
- import butterknife.BindView;
- import butterknife.ButterKnife;
-
- /**
- * Created by 張靜
- */
-
- public class CheckNotifyListActivity extends BaseActivity {
-
- public static final int RESULT_HAVE_CHANGE = 0x4000;
- private static final int LOAD_MESSAGE_COUNT = 500;
- @BindView(R.id.rcv_notify_list)
- RecyclerView mRecyclerView;
- private List<AddFriendNotify> mNotifyInfoList;
- private RecycleViewAdapter<AddFriendNotify> mAdapter;
- private boolean haveChange = false;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setStatusBarColor(R.color.app_blue_color);
- setContentView(R.layout.activity_check_notify);
- setTitleBar("驗證提醒", true, true);
- ButterKnife.bind(this);
- init();
- }
-
- private void init() {
- mNotifyInfoList = new ArrayList<>();
- mAdapter = new RecycleViewAdapter<AddFriendNotify>(this, mNotifyInfoList) {
- @Override
- public int setItemLayoutId(int position) {
- return R.layout.item_check_notify;
- }
-
- @Override
- public void bindView(RViewHolder holder, final int position) {
- final AddFriendNotify item = mNotifyInfoList.get(position);
- SystemMessage message = item.getMessage();
- NimUserInfo userInfo = item.getUserInfo();
- if (userInfo != null) {
- holder.setImageByUrl(CheckNotifyListActivity.this, R.id.iv_head_picture,
- userInfo.getAvatar(), R.mipmap.bg_img_defalut);
- holder.setText(R.id.tv_name, userInfo.getName());
- } else {
- holder.setImageResource(R.id.iv_head_picture, R.mipmap.bg_img_defalut);
- holder.setText(R.id.tv_name, message.getFromAccount());
- }
-
- holder.setText(R.id.tv_content, message.getContent());
-
- TextView tv_status = holder.getTextView(R.id.tv_status);
- TextView tv_agree = holder.getTextView(R.id.tv_do_agree);
- TextView tv_refuse = holder.getTextView(R.id.tv_do_refuse);
- if (message.getStatus() == SystemMessageStatus.declined) {
- tv_agree.setVisibility(View.GONE);
- tv_refuse.setVisibility(View.GONE);
- tv_status.setText("已拒絕");
- tv_status.setVisibility(View.VISIBLE);
- } else if (message.getStatus() == SystemMessageStatus.passed) {
- tv_agree.setVisibility(View.GONE);
- tv_refuse.setVisibility(View.GONE);
- tv_status.setText("已同意");
- tv_status.setVisibility(View.VISIBLE);
- } else if (message.getStatus() == SystemMessageStatus.init) {
- tv_status.setText("");
- tv_status.setVisibility(View.GONE);
- tv_agree.setVisibility(View.VISIBLE);
- tv_refuse.setVisibility(View.VISIBLE);
- }
- tv_agree.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dealRequest(item.getMessage().getFromAccount(), position, true);
- }
- });
-
- tv_refuse.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dealRequest(item.getMessage().getFromAccount(), position, false);
- }
- });
- }
- };
- mAdapter.setItemLongClickListener(new OnItemLongClickListener() {
- @Override
- public void onItemLongClick(RViewHolder holder, int position) {
- ignoreRequest(position);
- }
- });
-
- mAdapter.setItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(RViewHolder holder, int position) {
- showAccountInfo(position);
- }
- });
-
- mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
- mRecyclerView.setAdapter(mAdapter);
-
- // Tool Bar
- mIvBack.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
-
- // 初始化好友添加通知監聽,收到信息後刷新頁面
- NimSysMsgHandler.getInstance().setMessageListener(new SystemMessageListener() {
- @Override
- public void addFriendNotify() {
- loadAddFriendNotify();
- }
- });
-
- loadAddFriendNotify();
- }
-
- /**
- * 讀取好友添加通知數據
- */
- private void loadAddFriendNotify() {
- List<SystemMessageType> types = new ArrayList<>();
- types.add(SystemMessageType.AddFriend);
-
- // 獲取「添加朋友」消息列表
- List<SystemMessage> msgList = NIMClient.getService(SystemMessageService.class)
- .querySystemMessageByTypeBlock(types, 0, LOAD_MESSAGE_COUNT);
-
- // 根據對方賬戶,獲取賬戶信息,構建顯示 item 數據
- AddFriendNotify notify;
- List<AddFriendNotify> notifyInfoList = new ArrayList<>();
- for (SystemMessage message : msgList) {
- // 若用戶已選擇忽略這條消息,則跳過不顯示
- if (message.getStatus() == SystemMessageStatus.ignored) {
- continue;
- }
- NimUserInfo userInfo = NimUserHandler.getInstance().getUserInfo();
- //若獲取不到該條記錄的賬戶數據,也跳過不顯示
- if (userInfo == null) {
- return;
- }
-
- notify = new AddFriendNotify();
- notify.setMessage(message);
- notify.setMyFriend(NimFriendHandler.getInstance().CheckIsMyFriend(message.getFromAccount()));
- notify.setUserInfo(userInfo);
- notifyInfoList.add(notify);
- }
-
- // 刷新界面
- mNotifyInfoList.clear();
- mNotifyInfoList.addAll(notifyInfoList);
- mAdapter.notifyDataSetChanged();
-
- // 將「添加朋友」消息至爲已讀
- NIMClient.getService(SystemMessageService.class)
- .resetSystemMessageUnreadCountByType(types);
- }
-
- /**
- * 處理好友請求
- *
- * @param account 對方賬戶
- * @param position 列表位置
- * @param agree 是否同意
- */
- private void dealRequest(String account, int position, final boolean agree) {
- final SystemMessage message = mNotifyInfoList.get(position).getMessage();
- NIMClient.getService(FriendService.class)
- .ackAddFriendRequest(account, agree).setCallback(new RequestCallback<Void>() {
- @Override
- public void onSuccess(Void param) {
- SystemMessageStatus status;
- if (agree) {
- status = SystemMessageStatus.passed;
- } else {
- status = SystemMessageStatus.declined;
- }
- NIMClient.getService(SystemMessageService.class)
- .setSystemMessageStatus(message.getMessageId(), status);
- message.setStatus(status);
- mAdapter.notifyDataSetChanged();
- haveChange = true;
- }
-
- @Override
- public void onFailed(int code) {
- ToastUtils.showMessage(CheckNotifyListActivity.this, "處理失敗,code:" + code);
- }
-
- @Override
- public void onException(Throwable exception) {
- ToastUtils.showMessage(CheckNotifyListActivity.this, "處理出錯:" + exception.getMessage());
- }
- });
- }
-
- /**
- * 刪除並忽略該條記錄
- * @param position 所在位置
- */
- private void ignoreRequest(final int position) {
- new AlertDialog.Builder(this)
- .setMessage("是否刪除該條記錄?")
- .setCancelable(true)
- .setPositiveButton("確定", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SystemMessage message = mNotifyInfoList.get(position).getMessage();
- NIMClient.getService(SystemMessageService.class)
- .setSystemMessageStatus(message.getMessageId(),
- SystemMessageStatus.ignored);
- mNotifyInfoList.remove(position);
- mAdapter.notifyDataSetChanged();
- dialog.dismiss();
- new AlertDialog.Builder(this)
- .setMessage("是否刪除該條記錄?")
- .setCancelable(true)
- .setPositiveButton("確定", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SystemMessage message = mNotifyInfoList.get(position).getMessage();
- NIMClient.getService(SystemMessageService.class)
- .setSystemMessageStatus(message.getMessageId(),
- SystemMessageStatus.ignored);
- mNotifyInfoList.remove(position);
- mAdapter.notifyDataSetChanged();
- dialog.dismiss();
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- SystemMessage message = mNotifyInfoList.get(position).getMessage();
- NIMClient.getService(SystemMessageService.class)
- .setSystemMessageStatus(message.getMessageId(),
- SystemMessageStatus.ignored);
- mNotifyInfoList.remove(position);
- mAdapter.notifyDataSetChanged();
- dialog.dismiss();
- }
- })
- .setNegativeButton("取消", new DialogInterface.OnClickListener() {
- SystemMessageStatus.ignored);
- &nbs