实训第四周(2)
李晨晨:
本次主要实现图片和文件夹的属性描述和设置类,以及读取SD卡图片列表工具类。
1.重点是读取SD卡图片列表并保存到相应的list
- public class ImageUtils {
- public static void loadImageList(final Context context, final OnLoadImageCallBack callBack) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- ContentResolver resolver = context.getContentResolver();
- Cursor cursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- new String[]{MediaStore.Images.ImageColumns._ID,
- MediaStore.Images.ImageColumns.DATA,
- MediaStore.Images.ImageColumns.DISPLAY_NAME,
- MediaStore.Images.ImageColumns.SIZE,
- MediaStore.Images.ImageColumns.DATE_ADDED},
- null, null, MediaStore.Images.ImageColumns.DATE_ADDED + " desc");
- List<ImageBean> imageBeans = new ArrayList<>();
- if (cursor != null) {
- ImageBean bean;
- while (cursor.moveToNext()) {
- long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID));
- String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA));
- String name = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME));
- long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.ImageColumns.SIZE));
- long date = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_ADDED));
- bean = new ImageBean(id, name, path, size, date);
- imageBeans.add(bean);
- }
- cursor.close();
- }
- callBack.callBack(splitImage2Folder(imageBeans));
- }
- }).start();
- }
- private static List<FolderBean> splitImage2Folder(List<ImageBean> imageList) {
- List<FolderBean> folderList = new ArrayList<>();
- if (!imageList.isEmpty()) {
- // 生成全部图片文件夹
- FolderBean allFolder = new FolderBean("全部图片");
- for (ImageBean bean : imageList){
- if (bean.getSize() > 50 * 1024){
- allFolder.addImage(bean);
- }
- }
- folderList.add(allFolder);
- // 根据图片路径划分文件夹
- for (int i = 0; i < imageList.size(); i++) {
- String path = imageList.get(i).getPath();
- String name = getFolderName(path);
- if (!TextUtils.isEmpty(name)) {
- FolderBean folder = getFolder(name, folderList);
- folder.addImage(imageList.get(i));
- }
- }
- }
- return folderList;
- }
- private static String getFolderName(String path) {
- if (!TextUtils.isEmpty(path)) {
- String[] strings = path.split(File.separator);
- if (strings.length >= 2) {
- return strings[strings.length - 2];
- }
- }
- return "";
- }
- private static FolderBean getFolder(String name, List<FolderBean> folders) {
- for (int i = 0; i < folders.size(); i++) {
- FolderBean folder = folders.get(i);
- if (name.equals(folder.getName())) {
- return folder;
- }
- }
- FolderBean newFolder = new FolderBean(name);
- folders.add(newFolder);
- return newFolder;
- }
- public interface OnLoadImageCallBack {
- void callBack(List<FolderBean> folderList);
- }
- }
将所有的ImageBean都加到一个列表中,并用splitImage2Folder方法将所有图片划分到不同文件夹。所有过程完成后该线程产生一个callBack。
2.该过程中用到的ImageBean和FolderBean
- public class ImageBean implements Serializable{
- private long id;
- private String name;
- private String path;
- private long size;
- private long date;
- private boolean isSelected = false;
- public ImageBean() {
- }
- public ImageBean(long id, String name, String path, long size, long date) {
- this.id = id;
- this.name = name;
- this.path = path;
- this.size = size;
- this.date = date;
- }
- public long getId() {
- return id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPath() {
- return path;
- }
- public void setPath(String path) {
- this.path = path;
- }
- public long getSize() {
- return size;
- }
- public void setSize(long size) {
- this.size = size;
- }
- public long getDate() {
- return date;
- }
- public void setDate(long date) {
- this.date = date;
- }
- public boolean isSelected() {
- return isSelected;
- }
- public void setSelected(boolean selected) {
- isSelected = selected;
- }
- }
- public class FolderBean {
- private String name;
- private List<ImageBean> mImageList;
- private boolean isSelected = false;
- public FolderBean(String name) {
- this.name = name;
- }
- public FolderBean(String name, List<ImageBean> imageList) {
- this.name = name;
- mImageList = imageList;
- }
- public void addImage(ImageBean imageBean){
- if (mImageList == null){
- mImageList = new ArrayList<>();
- }
- mImageList.add(imageBean);
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public List<ImageBean> getImageList() {
- return mImageList;
- }
- public void setImageList(List<ImageBean> imageList) {
- mImageList = imageList;
- }
- public boolean isSelected() {
- return isSelected;
- }
- public void setSelected(boolean selected) {
- isSelected = selected;
- }
- }
仝心:
在前几次工作的基础上对已完成的工作部分进行了一定的整合,将个性化字体键盘文本输入功能、语音识别功能和原本的系统键盘功能组合到了一起,实现了文本输入布局的基本功能。
各种组件监听功能的初始化,包括文本框触摸、输入监听;表情输入监听。未来还将添加录音按钮初始化和录音监听。
- private void initListener() {
- // 文本输入框触摸监听
- mEtInput.setOnClickListener(new MyOnClickListener());
- // 文本输入框输入监听
- mEtInput.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- if (s.toString().length() > 0) {
- mIvMore.setVisibility(View.GONE);
- mBtnSend.setVisibility(View.VISIBLE);
- } else {
- mIvMore.setVisibility(View.VISIBLE);
- mBtnSend.setVisibility(View.GONE);
- }
- }
- @Override
- public void afterTextChanged(Editable s) {
- }
- });
- //表情输入监听
- mExpressLayout.setOnExpressSelListener(new ExpressLayout.OnExpressSelListener() {
- @Override
- public void onEmojiSelect(EmojiBean emojiBean) {
- // 如果点击了表情,则添加到输入框中
- int curPosition = mEtInput.getSelectionStart();
- String tag=mChangeModeLayout.getTag().toString();
- switch(tag){
- case "1":
- // 获取当前光标位置,在指定位置上添加表情图片文本
- StringBuilder sb = new StringBuilder(mEtInput.getText().toString());
- sb.insert(curPosition, emojiBean.getEmojiName());
- // 特殊文字处理,将表情等转换一下
- SpannableString spannableString = EmojiUtils.text2Emoji(getContext(),
- sb.toString(), mEtInput.getTextSize());
- mEtInput.setText(spannableString);
- // 将光标设置到新增完表情的右侧
- mEtInput.setSelection(curPosition + emojiBean.getEmojiName().length());
- break;
- case "2":
- //Drawable drawable = getResources().getDrawable(emojiBean.getResIndex());
- Bitmap bmp = BitmapFactory.decodeResource(getResources(),emojiBean.getResIndex());
- SpannableString ss=getBitmapMime(bmp);
- insertPhotoToEditText(ss);
- count++;
- inputBmpList.add(curPosition,bmp);
- break;
- default:
- break;
- }
- }
- @Override
- public void onEmojiDelete() {
- // 调用系统的删除操作
- mEtInput.dispatchKeyEvent(new KeyEvent(
- KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
- }
- });
- mEtInput.setFocusable(true);
- mEtInput.requestFocus();//否则第一次点文本框时会弹出系统键盘
- hideSoftInput(1);
- }
表情包按键的相关事件处理,以下的case1表示键盘输入模式,case2表示语音识别模式,case3表示录音模式(暂时还没有实现,将在接下来的工作中完成)。
- @OnClick(R.id.iv_expression)
- public void clickExpressBtn(){
- String tag=mIvInputType.getTag().toString();
- switch(tag){
- case "1":
- if(mExpressLayout.isShown())
- {
- lockContentHeight();
- mExpressLayout.setVisibility(GONE);
- mIvExpress.setImageResource(R.mipmap.expression);
- showSoftInput();
- unLockContentHeight();
- }else{
- if(isSoftInputShow()){
- lockContentHeight();
- hideSoftInput(3);
- }
- mExtensionLayout.setVisibility(GONE);
- mExpressLayout.setVisibility(VISIBLE);
- mIvExpress.setImageResource(R.mipmap.keyboard);
- unLockContentHeight();
- }
- break;
- case "2":
- if(mExpressLayout.isShown()){
- mExpressLayout.setVisibility(GONE);
- mIvExpress.setImageResource(R.mipmap.expression);
- mSoundRecogLayout.setVisibility(VISIBLE);
- }else{
- mExtensionLayout.setVisibility(GONE);
- mSoundRecogLayout.setVisibility(GONE);
- mExpressLayout.setVisibility(VISIBLE);
- mIvExpress.setImageResource(R.mipmap.keyboard);
- }
- break;
- case "3":
- break;
- default:
- break;
- }
- }
最后是针对发送键按钮的监听,这里分为了发送系统文本和自定义文本的两种情况,发送自定义文本是要先对打字过程中存储的所有图片进行拼接,包括字母间的左右拼接和行间的上下拼接,其中inputList中存储打字时产生的图片,currentList中存储当前拼接的图片。拼接完成后将拼接后的图片以发送图片的形式发送出去。
- //发送键,发送键
- @OnClick(R.id.tv_btn_send)
- public void sendTextMessage() {
- String tag=mChangeModeLayout.getTag().toString();
- switch (tag){
- case "1":
- //正常文本模式,系统键盘
- String text = mEtInput.getText().toString();
- mEtInput.getText().clear();
- //语音识别相关清空
- mIatResults.clear();
- result_string="";
- new_piece="";
- if (mLayoutListener != null) {
- mLayoutListener.sendBtnClick(text);
- }
- break;
- case "2":
- //个性化文本模式,自定义键盘
- Bitmap bitmap;//文本框所有图片合成的bitmap
- if(inputBmpList.size() == 0)
- break;
- else if(inputBmpList.size() == 1){
- bitmap = newBitmap(inputBmpList.get(0));
- }else {
- bitmap = newBitmap(inputBmpList.get(0));
- for (int i = 0; i < inputBmpList.size() - 1; i++) {
- if(bitmap.getWidth()<800)
- {
- bitmap = newBitmap(bitmap, inputBmpList.get(i + 1));
- }
- else{
- currentBmpList.add(bitmap);
- bitmap = null;
- bitmap = newBitmap(inputBmpList.get(i + 1));
- }
- }
- currentBmpList.add(bitmap);
- }
- int longest;
- if(currentBmpList.size()>0){
- bitmap = currentBmpList.get(0);
- }
- for(int i = 0;i< currentBmpList.size() - 1;i++){
- if(bitmap.getWidth()>currentBmpList.get(i+1).getWidth())
- longest = bitmap.getWidth();
- else
- longest = currentBmpList.get(i+1).getWidth();
- bitmap = newBitmap(bitmap,currentBmpList.get(i+1),longest);
- }
- bitmap = scaleBitmap(bitmap,0.6f);
- currentBmpList.clear();
- //将bitmap的背景色改为蓝色
- bitmap=changeBackground(bitmap);
- //将合成的图保存到指定路径,用于图片发送
- Bitmap bb;
- bb=bitmap.copy(Bitmap.Config.ARGB_8888,true);
- String pathName=Constant.APP_CACHE_IMAGE+System.currentTimeMillis()+".jpg";
- File dirFile=new File(pathName);
- if(!dirFile.exists()){
- dirFile.getParentFile().mkdir();
- try{
- dirFile.createNewFile();
- }catch(IOException e){
- e.printStackTrace();
- }
- }
- FileOutputStream out=null;
- try{
- out = new FileOutputStream(dirFile);
- bb.compress(Bitmap.CompressFormat.JPEG,90,out);
- System.out.println("-------------保存到sd指定目录文件下--------------");
- }catch(FileNotFoundException e){
- e.printStackTrace();
- }
- try{
- out.flush();
- out.close();
- }catch (IOException e){
- e.printStackTrace();
- }
- mEtInput.getText().clear();
- if (mLayoutListener != null) {
- mLayoutListener.photoTextBtnClick(pathName);
- }
- count = 0;
- inputBmpList.clear();
- break;
- default:
- break;
- }
- }
- //左右拼接
- private Bitmap newBitmap(Bitmap bit1,Bitmap bit2){
- int width = bit1.getWidth()+bit2.getWidth();
- int height = bit1.getHeight();
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- canvas.drawBitmap(bit1, 0, 0, null);
- canvas.drawBitmap(bit2, bit1.getWidth(), 0, null);
- return bitmap;
- }
- //上下拼接
- private Bitmap newBitmap(Bitmap bit1,Bitmap bit2,int length){
- int width = length;
- int height = bit1.getHeight()+bit2.getHeight();
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- canvas.drawBitmap(bit1, 0, 0, null);
- canvas.drawBitmap(bit2, 0, bit1.getHeight(), null);
- return bitmap;
- }
张静:
本周接下来完成了如下工作:
1. RequestFriendActivity(接上篇博客,当点击“添加到通讯录”时,跳转至此)
单击“发送请求”时,选择好友请求方式为VERIFY_REQUEST(发起好友验证请求)
通过NimClient的getService接口获取到FriendService(好友管理/好友关系/黑名单关系/消息提醒相关操作)服务实例,调用addFriend方法进行好友请求,附上信息msg
- package com.ezreal.ezchat.activity;
- import android.os.Bundle;
- import android.support.annotation.Nullable;
- import android.widget.EditText;
- import com.ezreal.ezchat.R;
- import com.netease.nimlib.sdk.InvocationFuture;
- import com.netease.nimlib.sdk.NIMClient;
- import com.netease.nimlib.sdk.RequestCallback;
- import com.netease.nimlib.sdk.RequestCallbackWrapper;
- import com.netease.nimlib.sdk.friend.FriendService;
- import com.netease.nimlib.sdk.friend.constant.VerifyType;
- import com.netease.nimlib.sdk.friend.model.AddFriendData;
- import com.ezreal.ezchat.commonlibrary.utils.ToastUtils;
- import butterknife.BindView;
- import butterknife.ButterKnife;
- import butterknife.OnClick;
- /**
- * Created by 张静
- */
- public class RequestFriendActivity extends BaseActivity {
- @BindView(R.id.et_request_msg)
- EditText mEtRequestMsg;
- private RequestCallback<Void> mRequestCallback;
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setStatusBarColor(R.color.app_blue_color);
- setContentView(R.layout.activity_request_friend);
- setTitleBar("添加好友",true,false);
- ButterKnife.bind(this);
- initCallBack();
- }
- private void initCallBack(){
- mRequestCallback = new RequestCallbackWrapper<Void>() {
- @Override
- public void onResult(int code, Void result, Throwable exception) {
- if (exception != null){
- ToastUtils.showMessage(RequestFriendActivity.this,"请求出错,请重试:" + exception.getMessage());
- }else {
- if (code == 200){
- ToastUtils.showMessage(RequestFriendActivity.this,"请求已发出~");
- finish();
- }else {
- ToastUtils.showMessage(RequestFriendActivity.this,"请求异常,请重试,异常代码:" + code);
- }
- }
- }
- };
- }
- @OnClick(R.id.tv_send_request)
- public void sendRequest(){
- String account = getIntent().getStringExtra("account");
- String msg = "";
- if (mEtRequestMsg.getText() != null){
- msg = mEtRequestMsg.getText().toString().trim();
- }
- VerifyType type = VerifyType.VERIFY_REQUEST;
- InvocationFuture<Void> addFriend = NIMClient.getService(FriendService.class)
- .addFriend(new AddFriendData(account, type, msg));
- addFriend.setCallback(mRequestCallback);
- }
- }
2. activity_request_friend.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"/>
- <EditText
- android:id="@+id/et_request_msg"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="50dp"
- android:hint="@string/request_friend_hint"
- android:textColorHint="@color/hint_color"
- android:background="@drawable/et_back_ground"/>
- <TextView
- android:id="@+id/tv_send_request"
- 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/send_request"/>
- </LinearLayout>
3. 继续接上篇中ContractFragment的内容,加载好友列表(loadFriendList)
通过NimFriendHandler获得好友信息,notifyDataSetChanged使如果适配器内容改变时需强制调用getView来刷新每个Item内容
- private void loadFriendList() {
- mFriendList.clear();
- mFriendList.addAll(NimFriendHandler.getInstance().getFriendInfos());
- mViewAdapter.notifyDataSetChanged();
- }
4. 点击“添加朋友”,跳转至SearchUserActivity(根据账户搜索用户)
- @OnClick(R.id.layout_add_friend)
- public void addFriend() {
- startActivity(new Intent(getContext(), SearchUserActivity.class));
- }
5. 点击“验证提醒”,跳转至CheckNotifyListActivity
- @OnClick(R.id.layout_msg_notify)
- public void openMsgNotifyActivity() {
- //hindUnReadMsgView();
- startActivityForResult(new Intent(getContext(),
- CheckNotifyListActivity.class), REQUEST_CHECK_NOTI);
- }
6. 得到新打开的Activity关闭后返回的数据
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_CHECK_NOTI) {
- if (resultCode == CheckNotifyListActivity.RESULT_HAVE_CHANGE) {
- loadFriendList();
- }
- }
- }
附上完整ContractFragment.java
- package com.ezreal.ezchat.fragment;
- import android.content.Intent;
- import android.support.v7.widget.LinearLayoutManager;
- import android.support.v7.widget.RecyclerView;
- import android.view.View;
- import android.widget.Toast;
- //import com.ezreal.chat.MainActivity;
- import com.ezreal.ezchat.R;
- import com.ezreal.ezchat.activity.FriendInfoActivity;
- import com.ezreal.ezchat.activity.CheckNotifyListActivity;
- import com.ezreal.ezchat.activity.SearchUserActivity;
- import com.ezreal.ezchat.handler.NimFriendHandler;
- import com.ezreal.ezchat.handler.NimFriendHandler.OnFriendUpdateListener;
- import com.ezreal.ezchat.handler.NimSysMsgHandler;
- import com.ezreal.ezchat.handler.NimSysMsgHandler.SystemMessageListener;
- import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
- import com.ezreal.ezchat.commonlibrary.adapter.OnItemClickListener;
- import com.ezreal.ezchat.commonlibrary.adapter.RViewHolder;
- import com.ezreal.ezchat.commonlibrary.adapter.RecycleViewAdapter;
- import com.ezreal.ezchat.commonlibrary.utils.TextUtils;
- import java.util.ArrayList;
- import java.util.List;
- import butterknife.BindView;
- import butterknife.ButterKnife;
- import butterknife.OnClick;
- /**
- * Created by 张静
- */
- public class ContractFragment extends BaseFragment {
- public static final int REQUEST_CHECK_NOTI = 0x5000;
- @BindView(R.id.rcv_friend)
- RecyclerView mRecyclerView;
- private List<NimUserInfo> mFriendList;
- private RecycleViewAdapter<NimUserInfo> mViewAdapter;
- @Override
- public int setLayoutID() {
- return R.layout.fragment_contract;
- }
- @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.putExtra("NimUserInfo", mFriendList.get(position));
- intent.putExtra("FLAG", FriendInfoActivity.FLAG_SHOW_FRIEND);
- startActivity(intent);
- }
- });
- mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
- mRecyclerView.setAdapter(mViewAdapter);
- NimFriendHandler.getInstance().setUpdateListener(new OnFriendUpdateListener() {
- @Override
- public void friendUpdate() {
- loadFriendList();
- }
- });
- loadFriendList();
- }
- private void loadFriendList() {
- mFriendList.clear();
- mFriendList.addAll(NimFriendHandler.getInstance().getFriendInfos());
- mViewAdapter.notifyDataSetChanged();
- }
- @OnClick(R.id.layout_add_friend)
- public void addFriend() {
- startActivity(new Intent(getContext(), SearchUserActivity.class));
- }
- @OnClick(R.id.layout_msg_notify)
- public void openMsgNotifyActivity() {
- //hindUnReadMsgView();
- startActivityForResult(new Intent(getContext(),
- CheckNotifyListActivity.class), REQUEST_CHECK_NOTI);
- }
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_CHECK_NOTI) {
- if (resultCode == CheckNotifyListActivity.RESULT_HAVE_CHANGE) {
- loadFriendList();
- }
- }
- }
- }