私聊改造:新增快速发送图片功能
This commit is contained in:
@@ -20,6 +20,7 @@ import android.view.WindowManager;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.Chronometer;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -27,7 +28,11 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.effective.android.panel.PanelSwitchHelper;
|
||||
import com.effective.android.panel.interfaces.PanelHeightMeasurer;
|
||||
import com.effective.android.panel.interfaces.listener.OnPanelChangeListener;
|
||||
@@ -35,6 +40,8 @@ import com.effective.android.panel.view.panel.IPanelView;
|
||||
import com.effective.android.panel.view.panel.PanelView;
|
||||
import com.mango.moshen.R;
|
||||
import com.mango.moshen.ui.im.actions.GiftAction;
|
||||
import com.mango.moshen.ui.im.adpter.PhotoPreviewAdapter;
|
||||
import com.mango.xchat_android_library.utils.ListUtils;
|
||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||
import com.mango.xchat_android_library.utils.SizeUtils;
|
||||
import com.netease.nim.uikit.api.NimUIKit;
|
||||
@@ -48,10 +55,14 @@ import com.netease.nim.uikit.business.session.emoji.EmoticonPickerView;
|
||||
import com.netease.nim.uikit.business.session.emoji.IEmoticonSelectedListener;
|
||||
import com.netease.nim.uikit.business.session.emoji.MoonUtil;
|
||||
import com.netease.nim.uikit.business.session.event.ActiveEvent;
|
||||
import com.netease.nim.uikit.business.session.helper.SendImageHelper;
|
||||
import com.netease.nim.uikit.business.session.module.Container;
|
||||
import com.netease.nim.uikit.business.session.module.input.ActionsPanel;
|
||||
import com.netease.nim.uikit.business.session.module.input.NimAudioChatEvent;
|
||||
import com.netease.nim.uikit.common.antispam.AntiSpamEvent;
|
||||
import com.netease.nim.uikit.common.media.picker.PickImageHelper;
|
||||
import com.netease.nim.uikit.common.media.picker.model.AlbumInfo;
|
||||
import com.netease.nim.uikit.common.media.picker.model.PhotoInfo;
|
||||
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
|
||||
import com.netease.nim.uikit.common.util.AntiSpamUtil;
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
@@ -73,8 +84,17 @@ import com.netease.nimlib.sdk.msg.model.IMMessage;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.ObservableSource;
|
||||
import io.reactivex.Scheduler;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.functions.Function;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* 底部文本编辑,语音等模块
|
||||
* Created by hzxuwen on 2015/6/16.
|
||||
@@ -84,11 +104,10 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
private static final String TAG = "MsgSendLayout";
|
||||
|
||||
private static final int SHOW_LAYOUT_DELAY = 0;
|
||||
|
||||
private final List<PhotoInfo> selectPhotos = new ArrayList<>();
|
||||
protected Container container;
|
||||
protected View view;
|
||||
protected Handler uiHandler;
|
||||
|
||||
protected EditText messageEditText;// 文本消息编辑框
|
||||
protected Button audioRecordBtn; // 录音按钮
|
||||
protected View audioAnimLayout; // 录音动画布局
|
||||
@@ -96,7 +115,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
protected View switchToTextButtonInInputBar;// 文本消息选择按钮
|
||||
protected View switchToAudioButtonInInputBar;// 语音消息选择按钮
|
||||
protected View sendMessageButtonInInputBar;// 发送消息按钮
|
||||
protected View emojiButtonInInputBar;// 发送消息按钮
|
||||
protected ImageView emojiButtonInInputBar;// 发送消息按钮
|
||||
protected View messageInputBar;
|
||||
// 表情
|
||||
protected EmoticonPickerView emoticonPickerView; // 贴图表情控件
|
||||
@@ -110,14 +129,13 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
private boolean started = false;
|
||||
private boolean cancelled = false;
|
||||
private boolean touched = false; // 是否按着
|
||||
private boolean isKeyboardShowed = true; // 是否显示键盘
|
||||
private boolean isKeyboardShowed = false; // 是否显示键盘
|
||||
private boolean isTextAudioSwitchShow; // 是否展示左侧语音按钮
|
||||
// adapter
|
||||
private List<BaseAction> actions;
|
||||
// data
|
||||
private long typingTime = 0;
|
||||
private TextWatcher aitTextWatcher;
|
||||
private volatile boolean disable;
|
||||
private boolean isChat;
|
||||
private PanelSwitchHelper mHelper;
|
||||
private final Runnable showTextRunnable = new Runnable() {
|
||||
@@ -129,6 +147,12 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
private ImageView ivImage;
|
||||
private ImageView ivCamera;
|
||||
private ImageView ivGift;
|
||||
private CheckBox cbOrigin;
|
||||
private TextView tvSendImage;
|
||||
private RecyclerView rvPreviewPhotos;
|
||||
private PhotoPreviewAdapter photoPreviewAdapter;
|
||||
private int previewPhotoNum;
|
||||
private TextView tvUserPhoto;
|
||||
/**
|
||||
* ************************* 键盘布局切换 *******************************
|
||||
*/
|
||||
@@ -152,7 +176,6 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
}
|
||||
mHelper.resetState();
|
||||
} else if (v == ivGift) {
|
||||
|
||||
ivGift.postDelayed(() -> {
|
||||
for (BaseAction action : actions) {
|
||||
if (action instanceof GiftAction) {
|
||||
@@ -162,7 +185,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
}
|
||||
}, !mHelper.isResetState() ? 300 : 0);
|
||||
mHelper.resetState();
|
||||
} else if (v == ivImage) {
|
||||
} else if (v == tvUserPhoto) {
|
||||
for (BaseAction action : actions) {
|
||||
if (action instanceof PhotoAction) {
|
||||
action.onClick();
|
||||
@@ -170,6 +193,29 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
}
|
||||
}
|
||||
mHelper.resetState();
|
||||
} else if (v == tvSendImage) {
|
||||
if (!isChat) {
|
||||
SingleToastUtil.showToast("暂未达到可发起私聊等级");
|
||||
return;
|
||||
}
|
||||
if (photoPreviewAdapter != null) {
|
||||
for (BaseAction action : actions) {
|
||||
if (action instanceof PhotoAction) {
|
||||
SendImageHelper.sendPhotos(container.activity, (PhotoAction) action, selectPhotos, cbOrigin.isChecked());
|
||||
selectPhotos.clear();
|
||||
for (PhotoInfo info : photoPreviewAdapter.getData()) {
|
||||
info.setIndex(0);
|
||||
info.setChoose(false);
|
||||
}
|
||||
previewPhotoNum = 0;
|
||||
tvSendImage.setEnabled(false);
|
||||
photoPreviewAdapter.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
mHelper.resetState();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -192,8 +238,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
int[] location = new int[2];
|
||||
view.getLocationOnScreen(location);
|
||||
|
||||
return event.getRawX() < location[0] || event.getRawX() > location[0] + view.getWidth()
|
||||
|| event.getRawY() < location[1] - 40;
|
||||
return event.getRawX() < location[0] || event.getRawX() > location[0] + view.getWidth() || event.getRawY() < location[1] - 40;
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
@@ -211,7 +256,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
}
|
||||
|
||||
public boolean collapse(boolean immediately) {
|
||||
boolean respond = !mHelper.isResetState();
|
||||
boolean respond = mHelper.isPanelState() || mHelper.isKeyboardState() || isKeyboardShowed;
|
||||
mHelper.resetState();
|
||||
return respond;
|
||||
}
|
||||
@@ -225,61 +270,56 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
initInputBarListener();
|
||||
initTextEdit();
|
||||
initAudioRecordButton();
|
||||
initPanelSwitchHelper();
|
||||
restoreText(false);
|
||||
|
||||
for (int i = 0; i < actions.size(); ++i) {
|
||||
actions.get(i).setIndex(i);
|
||||
actions.get(i).setContainer(container);
|
||||
}
|
||||
|
||||
if (disable) {
|
||||
disableButtons();
|
||||
}
|
||||
|
||||
private void initPanelSwitchHelper() {
|
||||
if (mHelper == null) {
|
||||
mHelper = new PanelSwitchHelper.Builder(container.activity)
|
||||
//可选
|
||||
.addKeyboardStateListener((visible, height) -> {
|
||||
Log.d(TAG, "系统键盘是否可见 : " + visible + " 高度为:" + height);
|
||||
})
|
||||
//可选
|
||||
.addEditTextFocusChangeListener((view, hasFocus) -> {
|
||||
Log.d(TAG, "输入框是否获得焦点 : " + hasFocus);
|
||||
})
|
||||
//可选
|
||||
.addViewClickListener(view -> {
|
||||
if (view == null) return;
|
||||
if (view.getId() == R.id.emoji_button) {
|
||||
switchToTextLayout(false);
|
||||
}
|
||||
Log.d(TAG, "点击了View : " + view);
|
||||
})
|
||||
//可选
|
||||
.addPanelChangeListener(new OnPanelChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onKeyboard() {
|
||||
Log.d(TAG, "唤起系统输入法");
|
||||
isKeyboardShowed = true;
|
||||
container.proxy.onInputPanelExpand();
|
||||
emojiButtonInInputBar.setImageResource(R.drawable.nim_message_input_emotion_pressed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNone() {
|
||||
Log.d(TAG, "隐藏所有面板");
|
||||
|
||||
isKeyboardShowed = false;
|
||||
emojiButtonInInputBar.setImageResource(R.drawable.nim_message_input_emotion_pressed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanel(IPanelView view) {
|
||||
Log.d(TAG, "唤起面板 : " + view);
|
||||
container.proxy.onInputPanelExpand();
|
||||
if (view.getBindingTriggerViewId() == R.id.emoji_button) {
|
||||
emojiButtonInInputBar.setImageResource(R.drawable.nim_message_input_keyboard);
|
||||
emoticonPickerView.show(InputPanel.this);
|
||||
} else if (view.getBindingTriggerViewId() == R.id.iv_image) {
|
||||
emojiButtonInInputBar.setImageResource(R.drawable.nim_message_input_emotion_pressed);
|
||||
initPreviewPhotos();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelSizeChange(IPanelView panelView, boolean portrait, int oldWidth, int oldHeight, int width, int height) {
|
||||
|
||||
}
|
||||
})
|
||||
.addPanelHeightMeasurer(new PanelHeightMeasurer() {
|
||||
}).addPanelHeightMeasurer(new PanelHeightMeasurer() {
|
||||
@Override
|
||||
public boolean synchronizeKeyboardHeight() {
|
||||
return false;
|
||||
@@ -294,8 +334,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
public int getPanelTriggerId() {
|
||||
return R.id.iv_image;
|
||||
}
|
||||
})
|
||||
.addPanelHeightMeasurer(new PanelHeightMeasurer() {
|
||||
}).addPanelHeightMeasurer(new PanelHeightMeasurer() {
|
||||
@Override
|
||||
public boolean synchronizeKeyboardHeight() {
|
||||
return false;
|
||||
@@ -310,8 +349,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
public int getPanelTriggerId() {
|
||||
return R.id.emoji_button;
|
||||
}
|
||||
})
|
||||
.logTrack(true)//output log
|
||||
}).logTrack(false)//output log
|
||||
.build();
|
||||
|
||||
messageListView.setPanelSwitchHelper(mHelper);
|
||||
@@ -319,6 +357,61 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void initPreviewPhotos() {
|
||||
if (photoPreviewAdapter != null) {
|
||||
photoPreviewAdapter.notifyDataSetChanged();
|
||||
return;
|
||||
}
|
||||
rvPreviewPhotos.setAdapter(photoPreviewAdapter = new PhotoPreviewAdapter());
|
||||
rvPreviewPhotos.setItemAnimator(null);
|
||||
rvPreviewPhotos.setLayoutManager(new LinearLayoutManager(container.activity, LinearLayoutManager.HORIZONTAL, false));
|
||||
photoPreviewAdapter.setOnItemClickListener((adapter, view, position) -> {
|
||||
PhotoInfo photoInfo = photoPreviewAdapter.getItem(position);
|
||||
if (photoInfo != null) {
|
||||
if (photoInfo.isChoose()) {
|
||||
photoInfo.setChoose(false);
|
||||
int tempIndex = photoInfo.getIndex();
|
||||
for (PhotoInfo info : photoPreviewAdapter.getData()) {
|
||||
if (info.getIndex() > tempIndex) {
|
||||
info.setIndex(info.getIndex() - 1);
|
||||
}
|
||||
}
|
||||
photoInfo.setIndex(0);
|
||||
previewPhotoNum--;
|
||||
selectPhotos.remove(tempIndex - 1);
|
||||
photoPreviewAdapter.notifyDataSetChanged();
|
||||
} else {
|
||||
if (previewPhotoNum >= 9) {
|
||||
SingleToastUtil.showToast("一次最多发送9张图片!");
|
||||
return;
|
||||
}
|
||||
previewPhotoNum++;
|
||||
photoInfo.setChoose(true);
|
||||
photoInfo.setIndex(previewPhotoNum);
|
||||
selectPhotos.add(photoInfo);
|
||||
photoPreviewAdapter.notifyItemChanged(position);
|
||||
}
|
||||
tvSendImage.setEnabled(previewPhotoNum > 0);
|
||||
}
|
||||
});
|
||||
|
||||
Observable.just(PickImageHelper.getAllMediaPhotos(container.activity, 40))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.flatMap(albumInfos -> {
|
||||
List<PhotoInfo> photoInfos = new ArrayList<>();
|
||||
for (AlbumInfo albumInfo : albumInfos) {
|
||||
if (!ListUtils.isListEmpty(albumInfo.getList())) {
|
||||
photoInfos.addAll(albumInfo.getList());
|
||||
}
|
||||
}
|
||||
return Observable.just(photoInfos);
|
||||
})
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(photoInfos -> photoPreviewAdapter.setNewData(photoInfos));
|
||||
}
|
||||
|
||||
|
||||
public void setCustomization(SessionCustomization customization) {
|
||||
this.customization = customization;
|
||||
if (customization != null) {
|
||||
@@ -331,6 +424,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
setCustomization(customization);
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void initViews() {
|
||||
messageInputBar = view.findViewById(R.id.textMessageLayout);
|
||||
switchToTextButtonInInputBar = view.findViewById(R.id.buttonTextMessage);
|
||||
@@ -348,8 +442,6 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
|
||||
// 表情
|
||||
emoticonPickerView = view.findViewById(R.id.emoticon_picker_view);
|
||||
emoticonPickerView.show(this);
|
||||
|
||||
// 显示录音按钮
|
||||
switchToTextButtonInInputBar.setVisibility(View.GONE);
|
||||
switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);
|
||||
@@ -369,27 +461,13 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
ivCamera.setOnClickListener(clickListener);
|
||||
ivGift.setOnClickListener(clickListener);
|
||||
|
||||
}
|
||||
|
||||
public void disableButtons() {
|
||||
if (messageEditText != null && audioRecordBtn != null &&
|
||||
switchToTextButtonInInputBar != null &&
|
||||
switchToAudioButtonInInputBar != null &&
|
||||
emojiButtonInInputBar != null) {
|
||||
messageEditText.setEnabled(false);
|
||||
messageEditText.setHint("禁言中,快找管理员解除禁言吧!");
|
||||
messageEditText.setHintTextColor(Color.parseColor("#999999"));
|
||||
audioRecordBtn.setEnabled(false);
|
||||
switchToTextButtonInInputBar.setEnabled(false);
|
||||
switchToAudioButtonInInputBar.setEnabled(false);
|
||||
emojiButtonInInputBar.setEnabled(false);
|
||||
} else {
|
||||
setDisable(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDisable(boolean disable) {
|
||||
this.disable = disable;
|
||||
rvPreviewPhotos = view.findViewById(R.id.rv_preview_photos);
|
||||
tvSendImage = view.findViewById(R.id.tv_send_image);
|
||||
tvSendImage.setEnabled(false);
|
||||
tvUserPhoto = view.findViewById(R.id.tv_user_photo);
|
||||
cbOrigin = view.findViewById(R.id.cb_origin);
|
||||
tvSendImage.setOnClickListener(clickListener);
|
||||
tvUserPhoto.setOnClickListener(clickListener);
|
||||
}
|
||||
|
||||
private void initInputBarListener() {
|
||||
@@ -405,9 +483,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
//当actionId == XX_SEND 或者 XX_DONE时都触发
|
||||
//或者event.getKeyCode == ENTER 且 event.getAction == ACTION_DOWN时也触发
|
||||
//注意,这是一定要判断event != null。因为在某些输入法上会返回null。
|
||||
if (actionId == EditorInfo.IME_ACTION_SEND
|
||||
|| actionId == EditorInfo.IME_ACTION_DONE
|
||||
|| (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode() && KeyEvent.ACTION_DOWN == event.getAction())) {
|
||||
if (actionId == EditorInfo.IME_ACTION_SEND || actionId == EditorInfo.IME_ACTION_DONE || (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode() && KeyEvent.ACTION_DOWN == event.getAction())) {
|
||||
//处理事件
|
||||
onTextMessageSendButtonPressed();
|
||||
return true;
|
||||
@@ -540,7 +616,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
// 切换成音频,收起键盘,按钮切换成键盘
|
||||
private void switchToAudioLayout() {
|
||||
if (!isChat) {
|
||||
SingleToastUtil.showToast("等级不够");
|
||||
SingleToastUtil.showToast("暂未达到可发起私聊等级");
|
||||
return;
|
||||
}
|
||||
Log.e(TAG, "switchToAudioLayout: ");
|
||||
@@ -559,10 +635,8 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
|
||||
// 隐藏键盘布局
|
||||
public void hideInputMethod() {
|
||||
isKeyboardShowed = false;
|
||||
uiHandler.removeCallbacks(showTextRunnable);
|
||||
InputMethodManager imm = (InputMethodManager) container.activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(messageEditText.getWindowToken(), 0);
|
||||
mHelper.resetState();
|
||||
messageEditText.clearFocus();
|
||||
}
|
||||
|
||||
@@ -572,9 +646,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
//如果已经显示,则继续操作时不需要把光标定位到最后
|
||||
if (!isKeyboardShowed) {
|
||||
editTextMessage.setSelection(editTextMessage.getText().length());
|
||||
isKeyboardShowed = true;
|
||||
}
|
||||
|
||||
mHelper.toKeyboardState();
|
||||
container.proxy.onInputPanelExpand();
|
||||
}
|
||||
@@ -594,7 +666,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
private void checkSendButtonEnable(EditText editText) {
|
||||
String textMessage = editText.getText().toString();
|
||||
setEditTextState();
|
||||
if (!TextUtils.isEmpty(StringUtil.removeBlanks(textMessage)) && editText.hasFocus()) {
|
||||
if (!TextUtils.isEmpty(StringUtil.removeBlanks(textMessage))) {
|
||||
sendMessageButtonInInputBar.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
sendMessageButtonInInputBar.setVisibility(View.GONE);
|
||||
@@ -631,8 +703,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
|
||||
@Override
|
||||
public void onTextAdd(String content, int start, int length) {
|
||||
if (messageEditText.getVisibility() != View.VISIBLE ||
|
||||
(emoticonPickerView != null && emoticonPickerView.getVisibility() == View.VISIBLE)) {
|
||||
if (messageEditText.getVisibility() != View.VISIBLE || (emoticonPickerView != null && emoticonPickerView.getVisibility() == View.VISIBLE)) {
|
||||
switchToTextLayout(true);
|
||||
} else {
|
||||
uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
|
||||
@@ -666,8 +737,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
touched = true;
|
||||
initAudioRecord();
|
||||
onStartAudioRecord();
|
||||
} else if (event.getAction() == MotionEvent.ACTION_CANCEL
|
||||
|| event.getAction() == MotionEvent.ACTION_UP) {
|
||||
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
|
||||
touched = false;
|
||||
onEndAudioRecord(isCancelled(v, event));
|
||||
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
@@ -693,8 +763,7 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
* 开始语音录制
|
||||
*/
|
||||
private void onStartAudioRecord() {
|
||||
container.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
|
||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
container.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
audioMessageHelper.startRecord();
|
||||
cancelled = false;
|
||||
}
|
||||
@@ -845,15 +914,6 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadActions(List<BaseAction> actions) {
|
||||
this.actions = actions;
|
||||
for (int i = 0; i < this.actions.size(); ++i) {
|
||||
this.actions.get(i).setIndex(i);
|
||||
this.actions.get(i).setContainer(container);
|
||||
}
|
||||
ActionsPanel.init(view, actions);
|
||||
}
|
||||
|
||||
public void setLimitLevel(boolean isChat, String msg) {
|
||||
this.isChat = isChat;
|
||||
setEditTextState();
|
||||
@@ -866,12 +926,22 @@ public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallba
|
||||
messageEditText.setFocusableInTouchMode(false);
|
||||
messageEditText.setEnabled(false);
|
||||
sendMessageButtonInInputBar.setEnabled(false);
|
||||
emojiButtonInInputBar.setEnabled(false);
|
||||
switchToAudioButtonInInputBar.setEnabled(false);
|
||||
ivImage.setEnabled(false);
|
||||
ivCamera.setEnabled(false);
|
||||
ivGift.setEnabled(false);
|
||||
} else {
|
||||
messageEditText.setHint("请输入消息");
|
||||
messageEditText.setFocusable(true);
|
||||
messageEditText.setFocusableInTouchMode(true);
|
||||
messageEditText.setEnabled(true);
|
||||
sendMessageButtonInInputBar.setEnabled(true);
|
||||
emojiButtonInInputBar.setEnabled(true);
|
||||
switchToAudioButtonInInputBar.setEnabled(true);
|
||||
ivImage.setEnabled(true);
|
||||
ivCamera.setEnabled(true);
|
||||
ivGift.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,29 @@
|
||||
package com.mango.moshen.ui.im.adpter
|
||||
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.bumptech.glide.signature.ObjectKey
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter
|
||||
import com.chad.library.adapter.base.BaseViewHolder
|
||||
import com.mango.core.utils.LogUtils
|
||||
import com.mango.moshen.R
|
||||
import com.mango.moshen.ui.utils.ImageLoadUtilsV2
|
||||
import com.netease.nim.uikit.common.media.picker.model.PhotoInfo
|
||||
import com.netease.nim.uikit.support.glide.GlideApp
|
||||
|
||||
class PhotoPreviewAdapter :
|
||||
BaseQuickAdapter<PhotoInfo, BaseViewHolder>(R.layout.item_message_photo) {
|
||||
|
||||
override fun convert(helper: BaseViewHolder, item: PhotoInfo) {
|
||||
val imageView = helper.getView<ImageView>(R.id.iv_item_photo)
|
||||
GlideApp.with(imageView)
|
||||
.load(item.filePath)
|
||||
.placeholder(R.drawable.default_cover)
|
||||
.signature(ObjectKey(item))
|
||||
.into(imageView)
|
||||
val textView = helper.getView<TextView>(R.id.tv_item_number)
|
||||
textView.isSelected = item.isChoose
|
||||
textView.text = if (item.isChoose) "${item.index}" else ""
|
||||
|
||||
}
|
||||
}
|
17
app/src/main/res/drawable/shape_circle_photo_preview_bg.xml
Normal file
17
app/src/main/res/drawable/shape_circle_photo_preview_bg.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="true">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#5FCCE4" />
|
||||
<stroke android:width="1dp" android:color="@color/white" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="@color/black_transparent_30" />
|
||||
<stroke android:width="1dp" android:color="@color/white" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
34
app/src/main/res/layout/item_message_photo.xml
Normal file
34
app/src/main/res/layout/item_message_photo.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="95dp"
|
||||
android:layout_height="138dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<com.mango.moshen.common.widget.RectRoundImageView
|
||||
android:id="@+id/iv_item_photo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
app:borderRadius="4dp"
|
||||
app:type="round" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_item_number"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_gravity="top|end"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:background="@drawable/shape_circle_photo_preview_bg"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_10"
|
||||
tools:text="1" />
|
||||
|
||||
</FrameLayout>
|
@@ -1,21 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_gravity="center">
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_preview_photos"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="154dp"
|
||||
android:background="@color/color_f4f4fa" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="46dp"
|
||||
android:background="@color/white"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nim_message_item_text_body"
|
||||
android:id="@+id/tv_user_photo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="phone|email|web"
|
||||
android:gravity="center_vertical|left"
|
||||
android:includeFontPadding="false"
|
||||
android:lineSpacingExtra="3dip"
|
||||
android:maxWidth="222dp"
|
||||
android:text="这是选择图片的玩意"
|
||||
android:textColor="@color/text_title_white"
|
||||
android:textSize="@dimen/dp_13" />
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="相册"
|
||||
android:textColor="@color/color_1A1A1A"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cb_origin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:button="@null"
|
||||
android:drawableStart="@drawable/selector_check_box_collect"
|
||||
android:drawablePadding="3dp"
|
||||
android:text="原图"
|
||||
android:textColor="@color/color_1A1A1A"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_send_image"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="@drawable/common_btn_bg"
|
||||
android:gravity="center"
|
||||
android:text="发送"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="10sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@@ -107,7 +107,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:layout_height="32dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
@@ -120,19 +120,19 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/buttonAudioMessage"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/nim_message_button_bottom_audio_selector"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:contentDescription="@string/empty"
|
||||
android:scaleType="center" />
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/nim_message_input_voice_pressed" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/buttonTextMessage"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:background="@drawable/nim_message_button_bottom_text_selector"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:contentDescription="@string/empty"
|
||||
android:scaleType="center"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/nim_message_input_keyboard"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -140,7 +140,7 @@
|
||||
<Button
|
||||
android:id="@+id/audioRecord"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||
android:layout_weight="1"
|
||||
@@ -153,11 +153,12 @@
|
||||
<EditText
|
||||
android:id="@+id/editTextMessage"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:autoLink="web|email|phone"
|
||||
android:background="@drawable/bg_message_input"
|
||||
android:gravity="center_vertical"
|
||||
android:hint="@string/message_hint"
|
||||
android:imeOptions="actionSend"
|
||||
android:inputType="text"
|
||||
@@ -172,12 +173,12 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/emoji_button"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||
android:background="@drawable/nim_message_button_bottom_emoji_selector"
|
||||
android:contentDescription="@string/empty"
|
||||
android:scaleType="center" />
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/nim_message_input_emotion_pressed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/buttonSendMessage"
|
||||
@@ -187,6 +188,7 @@
|
||||
android:background="@drawable/common_btn_bg"
|
||||
android:contentDescription="@string/empty"
|
||||
android:gravity="center"
|
||||
android:enabled="false"
|
||||
android:text="@string/send"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_12"
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.2 KiB |
@@ -3,6 +3,6 @@
|
||||
|
||||
<item android:drawable="@drawable/nim_message_input_emotion_pressed" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/nim_message_input_emotion_pressed" android:state_focused="true"/>
|
||||
<item android:drawable="@drawable/nim_message_input_emotion"/>
|
||||
<item android:drawable="@drawable/nim_message_input_emotion_pressed"/>
|
||||
|
||||
</selector>
|
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/color_grey_eaeaea" />
|
||||
<corners android:topLeftRadius="15dp"
|
||||
android:topRightRadius="15dp"
|
||||
android:bottomRightRadius="15dp"
|
||||
android:bottomLeftRadius="15dp"/>
|
||||
<corners android:topLeftRadius="8dp"
|
||||
android:topRightRadius="8dp"
|
||||
android:bottomRightRadius="8dp"
|
||||
android:bottomLeftRadius="8dp"/>
|
||||
</shape>
|
@@ -28,7 +28,7 @@ public class PhotoAction extends PickImageAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPicked(File file) {
|
||||
public void onPicked(File file) {
|
||||
IMMessage message;
|
||||
if (getContainer() != null && getContainer().sessionType == SessionTypeEnum.ChatRoom) {
|
||||
message = ChatRoomMessageBuilder.createChatRoomImageMessage(getAccount(), file, file.getName());
|
||||
|
@@ -54,7 +54,6 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
||||
}
|
||||
};
|
||||
private int categoryIndex;
|
||||
private Handler uiHandler;
|
||||
|
||||
public EmoticonPickerView(Context context) {
|
||||
super(context);
|
||||
@@ -75,7 +74,6 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
||||
|
||||
private void init(Context context) {
|
||||
this.context = context;
|
||||
this.uiHandler = new Handler(context.getMainLooper());
|
||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
inflater.inflate(R.layout.nim_emoji_layout, this);
|
||||
}
|
||||
@@ -222,7 +220,7 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
||||
@Override
|
||||
public void run() {
|
||||
if (scrollView.getChildAt(0).getWidth() == 0) {
|
||||
uiHandler.postDelayed(this, 100);
|
||||
scrollView.postDelayed(this, 100);
|
||||
}
|
||||
int x = -1;
|
||||
View child = tabView.getChildAt(index);
|
||||
@@ -236,7 +234,7 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
||||
}
|
||||
}
|
||||
};
|
||||
uiHandler.postDelayed(runnable, 100);
|
||||
scrollView.postDelayed(runnable, 100);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -8,6 +8,7 @@ import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.netease.nim.uikit.R;
|
||||
import com.netease.nim.uikit.business.session.actions.PhotoAction;
|
||||
import com.netease.nim.uikit.business.session.constant.Extras;
|
||||
import com.netease.nim.uikit.common.media.picker.model.PhotoInfo;
|
||||
import com.netease.nim.uikit.common.media.picker.model.PickerContract;
|
||||
@@ -24,10 +25,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SendImageHelper {
|
||||
public interface Callback {
|
||||
void sendImage(File file, boolean isOrig);
|
||||
}
|
||||
|
||||
public static void sendImageAfterPreviewPhotoActivityResult(Intent data, Callback callback) {
|
||||
final ArrayList<String> selectedImageFileList = data.getStringArrayListExtra(Extras.EXTRA_SCALED_IMAGE_LIST);
|
||||
final ArrayList<String> origSelectedImageFileList = data.getStringArrayListExtra(Extras.EXTRA_ORIG_IMAGE_LIST);
|
||||
@@ -88,6 +85,16 @@ public class SendImageHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPhotos(Context context, PhotoAction action, List<PhotoInfo> photos, boolean isOrig) {
|
||||
for (PhotoInfo photoInfo : photos) {
|
||||
new SendImageTask(context, isOrig, photoInfo, (file, isOrig1) -> action.onPicked(file)).execute();
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
void sendImage(File file, boolean isOrig);
|
||||
}
|
||||
|
||||
// 从相册选择图片进行发送(Added by NYB)
|
||||
public static class SendImageTask extends AsyncTask<Void, Void, File> {
|
||||
|
||||
|
@@ -128,4 +128,12 @@ public abstract class MsgViewHolderThumbBase extends MsgViewHolderBase {
|
||||
}
|
||||
|
||||
protected abstract String thumbFromSourceFile(String path);
|
||||
|
||||
protected int leftBackground() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected int rightBackground() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -2,10 +2,18 @@ package com.netease.nim.uikit.common.media.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.netease.nim.uikit.R;
|
||||
import com.netease.nim.uikit.business.session.module.input.NimImageActionEvent;
|
||||
import com.netease.nim.uikit.common.media.dao.MediaDAO;
|
||||
import com.netease.nim.uikit.common.media.picker.activity.PickImageActivity;
|
||||
import com.netease.nim.uikit.common.media.picker.model.AlbumInfo;
|
||||
import com.netease.nim.uikit.common.media.picker.model.PhotoInfo;
|
||||
import com.netease.nim.uikit.common.media.picker.util.ThumbnailsUtil;
|
||||
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog;
|
||||
import com.netease.nim.uikit.common.util.storage.StorageType;
|
||||
import com.netease.nim.uikit.common.util.storage.StorageUtil;
|
||||
@@ -13,11 +21,18 @@ import com.netease.nim.uikit.common.util.string.StringUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by huangjun on 2015/9/22.
|
||||
*/
|
||||
public class PickImageHelper {
|
||||
|
||||
public static final String FILE_PREFIX = "file://";
|
||||
|
||||
/**
|
||||
* 打开图片选择器
|
||||
*/
|
||||
@@ -72,6 +87,112 @@ public class PickImageHelper {
|
||||
EventBus.getDefault().post(event);
|
||||
}
|
||||
|
||||
public static ArrayList<AlbumInfo> getAllMediaPhotos(Context context, int limit) {
|
||||
getAllMediaThumbnails(context);
|
||||
ArrayList<AlbumInfo> albumInfolist = new ArrayList<>();
|
||||
|
||||
int num = 0;
|
||||
|
||||
Cursor cursorPhotos = null;
|
||||
try {
|
||||
cursorPhotos = MediaDAO.getAllMediaPhotos(context);
|
||||
HashMap<String, AlbumInfo> hash = new HashMap<>();
|
||||
AlbumInfo albumInfo;
|
||||
PhotoInfo photoInfo;
|
||||
|
||||
if (cursorPhotos != null && cursorPhotos.moveToFirst()) {
|
||||
do {
|
||||
int index = 0;
|
||||
int _id = cursorPhotos.getInt(cursorPhotos.getColumnIndex(MediaStore.Images.Media._ID));
|
||||
String path = cursorPhotos.getString(cursorPhotos.getColumnIndex(MediaStore.Images.Media.DATA));
|
||||
String album = cursorPhotos.getString(cursorPhotos.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
|
||||
long size = cursorPhotos.getLong(cursorPhotos.getColumnIndex(MediaStore.Images.Media.SIZE));
|
||||
|
||||
if (!isValidImageFile(path)) {
|
||||
Log.d("PICKER", "it is not a vaild path:" + path);
|
||||
continue;
|
||||
}
|
||||
num++;
|
||||
List<PhotoInfo> photoList = new ArrayList<>();
|
||||
photoInfo = new PhotoInfo();
|
||||
if (hash.containsKey(album)) {
|
||||
albumInfo = hash.remove(album);
|
||||
if (albumInfolist.contains(albumInfo))
|
||||
index = albumInfolist.indexOf(albumInfo);
|
||||
photoInfo.setImageId(_id);
|
||||
photoInfo.setFilePath(FILE_PREFIX + path);
|
||||
photoInfo.setAbsolutePath(path);
|
||||
photoInfo.setSize(size);
|
||||
albumInfo.getList().add(photoInfo);
|
||||
albumInfolist.set(index, albumInfo);
|
||||
hash.put(album, albumInfo);
|
||||
} else {
|
||||
albumInfo = new AlbumInfo();
|
||||
photoList.clear();
|
||||
photoInfo.setImageId(_id);
|
||||
photoInfo.setFilePath(FILE_PREFIX + path);
|
||||
photoInfo.setAbsolutePath(path);
|
||||
photoInfo.setSize(size);
|
||||
photoList.add(photoInfo);
|
||||
albumInfo.setImageId(_id);
|
||||
albumInfo.setFilePath(FILE_PREFIX + path);
|
||||
albumInfo.setAbsolutePath(path);
|
||||
albumInfo.setAlbumName(album);
|
||||
albumInfo.setList(photoList);
|
||||
albumInfolist.add(albumInfo);
|
||||
hash.put(album, albumInfo);
|
||||
}
|
||||
} while (cursorPhotos.moveToNext() && num < limit);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (cursorPhotos != null) {
|
||||
cursorPhotos.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return albumInfolist;
|
||||
}
|
||||
|
||||
private static void getAllMediaThumbnails(Context context) {
|
||||
ThumbnailsUtil.clear();
|
||||
Cursor cursorThumb = null;
|
||||
try {
|
||||
cursorThumb = MediaDAO.getAllMediaThumbnails(context);
|
||||
if (cursorThumb != null && cursorThumb.moveToFirst()) {
|
||||
int imageID;
|
||||
String imagePath;
|
||||
do {
|
||||
imageID = cursorThumb.getInt(cursorThumb.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID));
|
||||
imagePath = cursorThumb.getString(cursorThumb.getColumnIndex(MediaStore.Images.Thumbnails.DATA));
|
||||
ThumbnailsUtil.put(imageID, FILE_PREFIX + imagePath);
|
||||
} while (cursorThumb.moveToNext());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (cursorThumb != null) {
|
||||
cursorThumb.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidImageFile(String filePath) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
return false;
|
||||
}
|
||||
File imageFile = new File(filePath);
|
||||
return imageFile.exists();
|
||||
}
|
||||
|
||||
|
||||
public static class PickImageOption {
|
||||
/**
|
||||
* 图片选择器标题
|
||||
|
@@ -1,13 +1,8 @@
|
||||
package com.netease.nim.uikit.common.media.picker.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.database.Cursor;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.MediaStore.Images.Thumbnails;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -19,33 +14,21 @@ import android.widget.TextView;
|
||||
|
||||
import com.netease.nim.uikit.R;
|
||||
import com.netease.nim.uikit.common.fragment.TFragment;
|
||||
import com.netease.nim.uikit.common.media.dao.MediaDAO;
|
||||
import com.netease.nim.uikit.common.media.picker.PickImageHelper;
|
||||
import com.netease.nim.uikit.common.media.picker.adapter.PickerAlbumAdapter;
|
||||
import com.netease.nim.uikit.common.media.picker.model.AlbumInfo;
|
||||
import com.netease.nim.uikit.common.media.picker.model.PhotoInfo;
|
||||
import com.netease.nim.uikit.common.media.picker.util.ThumbnailsUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class PickerAlbumFragment extends TFragment implements OnItemClickListener {
|
||||
public interface OnAlbumItemClickListener {
|
||||
public void OnAlbumItemClick(AlbumInfo info);
|
||||
}
|
||||
|
||||
private OnAlbumItemClickListener onAlbumItemClickListener;
|
||||
private LinearLayout loadingLay;
|
||||
private TextView loadingTips;
|
||||
private TextView loadingEmpty;
|
||||
private ListView albumListView;
|
||||
|
||||
public static final String FILE_PREFIX = "file://";
|
||||
|
||||
private List<AlbumInfo> albumInfolist = new ArrayList<AlbumInfo>();
|
||||
|
||||
private List<AlbumInfo> albumInfolist = new ArrayList<>();
|
||||
private PickerAlbumAdapter albumAdapter;
|
||||
|
||||
public PickerAlbumFragment() {
|
||||
@@ -90,13 +73,31 @@ public class PickerAlbumFragment extends TFragment implements OnItemClickListene
|
||||
new ImageScanAsyncTask().execute();
|
||||
}
|
||||
|
||||
|
||||
private void getAllMediaPhotos() {
|
||||
if (albumInfolist == null) {
|
||||
albumInfolist = new ArrayList<>();
|
||||
} else {
|
||||
albumInfolist.clear();
|
||||
}
|
||||
|
||||
albumInfolist.addAll(PickImageHelper.getAllMediaPhotos(getActivity(),Integer.MAX_VALUE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
|
||||
onAlbumItemClickListener.OnAlbumItemClick(albumInfolist.get(position));
|
||||
}
|
||||
|
||||
public interface OnAlbumItemClickListener {
|
||||
void OnAlbumItemClick(AlbumInfo info);
|
||||
}
|
||||
|
||||
private class ImageScanAsyncTask extends AsyncTask<Void, Void, Object> {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground(Void... params) {
|
||||
getAllMediaThumbnails();
|
||||
getAllMediaPhotos();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -117,118 +118,4 @@ public class PickerAlbumFragment extends TFragment implements OnItemClickListene
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getAllMediaThumbnails() {
|
||||
ThumbnailsUtil.clear();
|
||||
Cursor cursorThumb = null;
|
||||
try {
|
||||
cursorThumb = MediaDAO.getAllMediaThumbnails(getActivity());
|
||||
if (cursorThumb != null && cursorThumb.moveToFirst()) {
|
||||
int imageID;
|
||||
String imagePath;
|
||||
do {
|
||||
imageID = cursorThumb.getInt(cursorThumb.getColumnIndex(Thumbnails.IMAGE_ID));
|
||||
imagePath = cursorThumb.getString(cursorThumb.getColumnIndex(Thumbnails.DATA));
|
||||
ThumbnailsUtil.put(imageID, FILE_PREFIX + imagePath);
|
||||
} while (cursorThumb.moveToNext());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (cursorThumb != null) {
|
||||
cursorThumb.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getAllMediaPhotos() {
|
||||
if (albumInfolist == null) {
|
||||
albumInfolist = new ArrayList<AlbumInfo>();
|
||||
} else {
|
||||
albumInfolist.clear();
|
||||
}
|
||||
|
||||
Cursor cursorPhotos = null;
|
||||
try {
|
||||
cursorPhotos = MediaDAO.getAllMediaPhotos(getActivity());
|
||||
HashMap<String, AlbumInfo> hash = new HashMap<String, AlbumInfo>();
|
||||
AlbumInfo albumInfo = null;
|
||||
PhotoInfo photoInfo = null;
|
||||
|
||||
if (cursorPhotos != null && cursorPhotos.moveToFirst()) {
|
||||
do {
|
||||
int index = 0;
|
||||
int _id = cursorPhotos.getInt(cursorPhotos.getColumnIndex(MediaStore.Images.Media._ID));
|
||||
String path = cursorPhotos.getString(cursorPhotos.getColumnIndex(MediaStore.Images.Media.DATA));
|
||||
String album = cursorPhotos.getString(cursorPhotos.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
|
||||
long size = cursorPhotos.getLong(cursorPhotos.getColumnIndex(MediaStore.Images.Media.SIZE));
|
||||
|
||||
if (!isValidImageFile(path)) {
|
||||
Log.d("PICKER", "it is not a vaild path:" + path);
|
||||
continue;
|
||||
}
|
||||
|
||||
List<PhotoInfo> photoList = new ArrayList<PhotoInfo>();
|
||||
photoInfo = new PhotoInfo();
|
||||
if (hash.containsKey(album)) {
|
||||
albumInfo = hash.remove(album);
|
||||
if (albumInfolist.contains(albumInfo))
|
||||
index = albumInfolist.indexOf(albumInfo);
|
||||
photoInfo.setImageId(_id);
|
||||
photoInfo.setFilePath(FILE_PREFIX + path);
|
||||
photoInfo.setAbsolutePath(path);
|
||||
photoInfo.setSize(size);
|
||||
albumInfo.getList().add(photoInfo);
|
||||
albumInfolist.set(index, albumInfo);
|
||||
hash.put(album, albumInfo);
|
||||
} else {
|
||||
albumInfo = new AlbumInfo();
|
||||
photoList.clear();
|
||||
photoInfo.setImageId(_id);
|
||||
photoInfo.setFilePath(FILE_PREFIX + path);
|
||||
photoInfo.setAbsolutePath(path);
|
||||
photoInfo.setSize(size);
|
||||
photoList.add(photoInfo);
|
||||
albumInfo.setImageId(_id);
|
||||
albumInfo.setFilePath(FILE_PREFIX + path);
|
||||
albumInfo.setAbsolutePath(path);
|
||||
albumInfo.setAlbumName(album);
|
||||
albumInfo.setList(photoList);
|
||||
albumInfolist.add(albumInfo);
|
||||
hash.put(album, albumInfo);
|
||||
}
|
||||
} while (cursorPhotos.moveToNext());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (cursorPhotos != null) {
|
||||
cursorPhotos.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidImageFile(String filePath) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
File imageFile = new File(filePath);
|
||||
if (imageFile.exists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
|
||||
onAlbumItemClickListener.OnAlbumItemClick(albumInfolist.get(position));
|
||||
}
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ public class PhotoInfo implements Serializable {
|
||||
private String absolutePath;
|
||||
private long size;
|
||||
private boolean choose = false;
|
||||
private int index;
|
||||
|
||||
public int getImageId() {
|
||||
return imageId;
|
||||
@@ -51,4 +52,24 @@ public class PhotoInfo implements Serializable {
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PhotoInfo{" +
|
||||
"imageId=" + imageId +
|
||||
", filePath='" + filePath + '\'' +
|
||||
", absolutePath='" + absolutePath + '\'' +
|
||||
", size=" + size +
|
||||
", choose=" + choose +
|
||||
", index=" + index +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user