From 0fce76024bc895763c25ee60e0a8a569375fb36f Mon Sep 17 00:00:00 2001 From: jinfeng Date: Thu, 16 May 2019 17:38:00 +0800 Subject: [PATCH 01/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=AE=A4=E5=88=97=E8=A1=A8=E4=B8=8A=E6=8B=89=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=20IM-5389?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chatapp/build.gradle | 2 +- .../activity/fragment/ChatRoomFragment.java | 3 +- .../chat/controller/ChatRoomController.java | 29 ++++++--------- .../java/jiguang/chat/view/ChatRoomView.java | 19 ++++++---- .../main/res/layout/fragment_chat_room.xml | 36 ++++++++++++++++--- 5 files changed, 56 insertions(+), 33 deletions(-) diff --git a/chatapp/build.gradle b/chatapp/build.gradle index b7ce2ced..bf8ed97d 100644 --- a/chatapp/build.gradle +++ b/chatapp/build.gradle @@ -72,5 +72,5 @@ dependencies { implementation 'cn.jiguang.sdk:jmessage:2.9.0' // 此处以J implementation 'cn.jiguang.sdk:jcore:2.0.0' implementation 'org.greenrobot:eventbus:3.1.1' - implementation 'in.srain.cube:ptr-load-more:1.0.6' + implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-25' } diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/ChatRoomFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/ChatRoomFragment.java index 05bf5e7c..ecdcdcbd 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/fragment/ChatRoomFragment.java +++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/ChatRoomFragment.java @@ -33,7 +33,8 @@ public void onCreate(Bundle savedInstanceState) { mChatRoomView.setListener(mRoomController); mChatRoomView.setClickListener(mRoomController); - mChatRoomView.setPtrHandler(mRoomController); + mChatRoomView.setOnRefreshListener(mRoomController); + mChatRoomView.setOnLoadMoreListener(mRoomController); } @Override diff --git a/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java b/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java index d1bef7fe..921a9935 100644 --- a/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java +++ b/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java @@ -3,9 +3,14 @@ import android.app.Dialog; import android.content.Context; import android.content.Intent; +import android.support.annotation.NonNull; import android.view.View; import android.widget.AdapterView; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; + import java.util.ArrayList; import java.util.List; @@ -13,10 +18,6 @@ import cn.jpush.im.android.api.callback.RequestCallback; import cn.jpush.im.android.api.enums.ConversationType; import cn.jpush.im.android.api.model.ChatRoomInfo; -import in.srain.cube.views.ptr.PtrDefaultHandler; -import in.srain.cube.views.ptr.PtrDefaultHandler2; -import in.srain.cube.views.ptr.PtrFrameLayout; -import in.srain.cube.views.ptr.PtrHandler2; import jiguang.chat.R; import jiguang.chat.activity.ChatActivity; import jiguang.chat.activity.SearchChatRoomActivity; @@ -30,7 +31,7 @@ * Created by ${chenyn} on 2017/10/31. */ -public class ChatRoomController implements AdapterView.OnItemClickListener, View.OnClickListener, PtrHandler2 { +public class ChatRoomController implements AdapterView.OnItemClickListener, View.OnClickListener, OnRefreshListener, OnLoadMoreListener { private ChatRoomView mChatRoomView; private Context mContext; private static final int PAGE_COUNT = 15; @@ -84,12 +85,7 @@ public void onClick(View v) { } @Override - public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) { - return PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header); - } - - @Override - public void onRefreshBegin(PtrFrameLayout frame) { + public void onRefresh(@NonNull RefreshLayout refreshLayout) { ChatRoomManager.getChatRoomListByApp(0, PAGE_COUNT, new RequestCallback>() { @Override public void gotResult(int i, String s, List result) { @@ -102,18 +98,13 @@ public void gotResult(int i, String s, List result) { } else { HandleResponseCode.onHandle(mContext, i, false); } - frame.refreshComplete(); + refreshLayout.finishRefresh(); } }); } @Override - public boolean checkCanDoLoadMore(PtrFrameLayout frame, View content, View footer) { - return PtrDefaultHandler2.checkContentCanBePulledUp(frame, content, footer); - } - - @Override - public void onLoadMoreBegin(PtrFrameLayout frame) { + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { ChatRoomManager.getChatRoomListByApp(chatRoomInfos.size(), PAGE_COUNT, new RequestCallback>() { @Override public void gotResult(int i, String s, List result) { @@ -125,7 +116,7 @@ public void gotResult(int i, String s, List result) { } else { HandleResponseCode.onHandle(mContext, i, false); } - frame.refreshComplete(); + refreshLayout.finishLoadMore(); } }); } diff --git a/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java b/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java index 538c8683..bd10a78d 100644 --- a/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java +++ b/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java @@ -9,8 +9,10 @@ import android.widget.ListView; import android.widget.TextView; -import in.srain.cube.views.ptr.PtrFrameLayout; -import in.srain.cube.views.ptr.PtrHandler; +import com.scwang.smartrefresh.layout.SmartRefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; + import jiguang.chat.R; import jiguang.chat.adapter.ChatRoomAdapter; import jiguang.chat.controller.ChatRoomController; @@ -25,7 +27,7 @@ public class ChatRoomView extends LinearLayout{ private ListView mChatRoomListView; private LayoutInflater mInflater; private LinearLayout mSearch_title; - private PtrFrameLayout ptrFrameLayout; + private SmartRefreshLayout smartRefreshLayout; public ChatRoomView(Context context) { super(context); @@ -45,8 +47,7 @@ public void initModule() { mSearch_title = view.findViewById(R.id.search_title); mChatRoomListView = findViewById(R.id.lv_chatRoom); mChatRoomListView.addHeaderView(view); - ptrFrameLayout = findViewById(R.id.ptr_layout); - ptrFrameLayout.setResistanceFooter(1.0f); + smartRefreshLayout = findViewById(R.id.refreshLayout); } public void setListener(ChatRoomController listener) { @@ -61,8 +62,12 @@ public void setChatRoomAdapter(ChatRoomAdapter chatRoomAdapter) { mChatRoomListView.setAdapter(chatRoomAdapter); } - public void setPtrHandler(PtrHandler ptrHandler) { - ptrFrameLayout.setPtrHandler(ptrHandler); + public void setOnRefreshListener(OnRefreshListener onRefreshListener) { + smartRefreshLayout.setOnRefreshListener(onRefreshListener); + } + + public void setOnLoadMoreListener(OnLoadMoreListener loadMoreListener) { + smartRefreshLayout.setOnLoadMoreListener(loadMoreListener); } } diff --git a/chatapp/src/main/res/layout/fragment_chat_room.xml b/chatapp/src/main/res/layout/fragment_chat_room.xml index 7ab2c80c..971d998f 100644 --- a/chatapp/src/main/res/layout/fragment_chat_room.xml +++ b/chatapp/src/main/res/layout/fragment_chat_room.xml @@ -46,11 +46,17 @@ android:textSize="16sp" android:visibility="gone"/> - - + android:layout_height="match_parent" + app:srlEnablePreviewInEditMode="true"> + + + - + + + + + + + + + + + + + + + + + + + From da5883204fd1773a4c700e7d6cc854d4c3bdae36 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Fri, 17 May 2019 15:52:27 +0800 Subject: [PATCH 02/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=AE=A4=E5=8F=91=E9=80=81=E5=90=8D=E7=89=87=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E4=BC=9A=E5=B4=A9=E6=BA=83=E7=9A=84=E9=97=AE=E9=A2=98=20IM-539?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jiguang/chat/activity/ChatActivity.java | 36 ++++++++++++++----- .../chat/activity/FriendListActivity.java | 29 ++++++++++++--- .../chat/application/JGApplication.java | 2 ++ 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java index a5e71f41..dcb7ce0f 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java @@ -673,16 +673,18 @@ protected void onPause() { @Override protected void onResume() { String targetId = getIntent().getStringExtra(TARGET_ID); - if (!mIsSingle) { + if (mIsSingle) { + if (null != targetId) { + String appKey = getIntent().getStringExtra(TARGET_APP_KEY); + JMessageClient.enterSingleConversation(targetId, appKey); + } + } else if (!isChatRoom) { long groupId = getIntent().getLongExtra(GROUP_ID, 0); if (groupId != 0) { JGApplication.isAtMe.put(groupId, false); JGApplication.isAtall.put(groupId, false); JMessageClient.enterGroupConversation(groupId); } - } else if (null != targetId) { - String appKey = getIntent().getStringExtra(TARGET_APP_KEY); - JMessageClient.enterSingleConversation(targetId, appKey); } //历史消息中删除后返回到聊天界面刷新界面 @@ -695,7 +697,9 @@ protected void onResume() { mChatAdapter.notifyDataSetChanged(); //发送名片返回聊天界面刷新信息 if (SharePreferenceManager.getIsOpen()) { - initData(); + if (!isChatRoom) { + initData(); + } SharePreferenceManager.setIsOpen(false); } super.onResume(); @@ -1147,10 +1151,10 @@ public void onEventMainThread(ImageEvent event) { break; case JGApplication.BUSINESS_CARD: intent = new Intent(mContext, FriendListActivity.class); - intent.putExtra("isSingle", mIsSingle); - intent.putExtra("userId", mTargetId); - intent.putExtra("groupId", mGroupId); - startActivity(intent); + intent.putExtra(JGApplication.CONV_TYPE, mConv.getType()); + intent.putExtra(JGApplication.TARGET_ID, mTargetId); + intent.putExtra(JGApplication.TARGET_APP_KEY, mTargetAppKey);; + startActivityForResult(intent, JGApplication.REQUEST_CODE_FRIEND_LIST); break; case JGApplication.TACK_VIDEO: case JGApplication.TACK_VOICE: @@ -1173,6 +1177,20 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { case RequestCode.PICK_IMAGE://4 onPickImageActivityResult(requestCode, data); break; + case JGApplication.REQUEST_CODE_FRIEND_LIST: + // 发送名片成功后,聊天室需要添加消息 + if (resultCode == RESULT_OK && isChatRoom) { + String msgJson = data.getStringExtra(JGApplication.MSG_JSON); + if (msgJson != null) { + Message msg = Message.fromJson(msgJson); + if (msg != null) { + mChatAdapter.addMsgToList(msg); + mChatAdapter.notifyDataSetChanged(); + } + } + } + break; + } switch (resultCode) { diff --git a/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java b/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java index 12034e26..d3b5aa7d 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java @@ -17,12 +17,14 @@ import cn.jpush.im.android.api.JMessageClient; import cn.jpush.im.android.api.content.TextContent; +import cn.jpush.im.android.api.enums.ConversationType; import cn.jpush.im.android.api.model.Conversation; import cn.jpush.im.android.api.model.Message; import cn.jpush.im.android.api.options.MessageSendingOptions; import cn.jpush.im.api.BasicCallback; import jiguang.chat.R; import jiguang.chat.adapter.FriendListAdapter; +import jiguang.chat.application.JGApplication; import jiguang.chat.database.FriendEntry; import jiguang.chat.database.UserEntry; import jiguang.chat.utils.DialogCreator; @@ -87,10 +89,26 @@ public void onClick(View v) { public void onItemClick(AdapterView parent, View view, int position, long id) { Object itemAtPosition = parent.getItemAtPosition(position); FriendEntry friendEntry = (FriendEntry) itemAtPosition; - if (getIntent().getBooleanExtra("isSingle", false)) { - setBusinessCard(friendEntry, JMessageClient.getSingleConversation(getIntent().getStringExtra("userId"))); - } else { - setBusinessCard(friendEntry, JMessageClient.getGroupConversation(getIntent().getLongExtra("groupId", 0))); + ConversationType convType = (ConversationType) getIntent().getSerializableExtra(JGApplication.CONV_TYPE); + String targetId = getIntent().getStringExtra(JGApplication.TARGET_ID); + String targetAppKey = getIntent().getStringExtra(JGApplication.TARGET_APP_KEY); + Conversation conv = null; + if (convType != null) { + switch (convType) { + case single: + conv = JMessageClient.getSingleConversation(targetId, targetAppKey); + break; + case group: + conv = JMessageClient.getGroupConversation(Long.valueOf(targetId)); + break; + case chatroom: + conv = JMessageClient.getChatRoomConversation(Long.valueOf(targetId)); + break; + default: + } + } + if (conv != null) { + setBusinessCard(friendEntry, conv); } } }); @@ -133,6 +151,9 @@ public void gotResult(int i, String s) { if (i == 0) { SharePreferenceManager.setIsOpen(true); Toast.makeText(FriendListActivity.this, "发送成功", Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(); + intent.putExtra(JGApplication.MSG_JSON, textMessage.toJson()); + FriendListActivity.this.setResult(RESULT_OK, intent); finish(); } else { HandleResponseCode.onHandle(FriendListActivity.this, i, false); diff --git a/chatapp/src/main/java/jiguang/chat/application/JGApplication.java b/chatapp/src/main/java/jiguang/chat/application/JGApplication.java index a08fe24e..817c7a52 100644 --- a/chatapp/src/main/java/jiguang/chat/application/JGApplication.java +++ b/chatapp/src/main/java/jiguang/chat/application/JGApplication.java @@ -77,6 +77,7 @@ public class JGApplication extends com.activeandroid.app.Application { public static final int REQUEST_CODE_SEND_LOCATION = 24; public static final int REQUEST_CODE_FRIEND_INFO = 16; public static final int RESULT_CODE_CHAT_DETAIL = 15; + public static final int REQUEST_CODE_FRIEND_LIST = 17; public static final int ON_GROUP_EVENT = 3004; public static final String DELETE_MODE = "deleteMode"; public static final int RESULT_CODE_ME_INFO = 20; @@ -87,6 +88,7 @@ public class JGApplication extends com.activeandroid.app.Application { public static final String GROUP_ID = "groupId"; public static final String POSITION = "position"; public static final String MsgIDs = "msgIDs"; + public static final String MSG_JSON = "msg_json"; public static final String MSG_LIST_JSON = "msg_list_json"; public static final String NAME = "name"; public static final String ATALL = "atall"; From 5db8e61c672d25e7f006b0dd560e546fd95fa4e1 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Fri, 17 May 2019 17:13:38 +0800 Subject: [PATCH 03/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BD=AC=E5=8F=91?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=B4=A9=E6=BA=83=E9=97=AE=E9=A2=98=E5=92=8C?= =?UTF-8?q?=E5=B1=8F=E8=94=BD=E8=81=8A=E5=A4=A9=E5=AE=A4=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E9=95=BF=E6=8C=89=E5=93=8D=E5=BA=94=20IM-5394?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java | 3 +++ .../main/java/jiguang/chat/activity/ForwardMsgActivity.java | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java index dcb7ce0f..8383f5aa 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java @@ -877,6 +877,9 @@ private void refreshGroupNum() { @Override public void onContentLongClick(final int position, View view) { + if (isChatRoom) { + return; + } final Message msg = mChatAdapter.getMessage(position); if (msg == null) { diff --git a/chatapp/src/main/java/jiguang/chat/activity/ForwardMsgActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ForwardMsgActivity.java index 75aa7f9b..561f3e44 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/ForwardMsgActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/ForwardMsgActivity.java @@ -15,6 +15,7 @@ import cn.jpush.im.android.api.JMessageClient; import cn.jpush.im.android.api.content.TextContent; +import cn.jpush.im.android.api.enums.ConversationType; import cn.jpush.im.android.api.model.Conversation; import cn.jpush.im.android.api.model.Message; import cn.jpush.im.android.api.options.MessageSendingOptions; @@ -64,7 +65,7 @@ private void initView() { private void initData() { List conversationList = JMessageClient.getConversationList(); for (Conversation conv : conversationList) { - if (!conv.getTargetId().equals("feedback_Android")) { + if (!conv.getTargetId().equals("feedback_Android") && conv.getType() != ConversationType.chatroom) { forwardList.add(conv); } } From 4416e887c7342b93d98b62bc8877ff13bc1f9d52 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Mon, 20 May 2019 15:24:06 +0800 Subject: [PATCH 04/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=91=E9=80=81?= =?UTF-8?q?=E5=B0=8F=E8=A7=86=E9=A2=91=E8=BF=87=E7=A8=8B=E4=B8=AD=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=B1=95=E7=A4=BA=E4=B8=8D=E5=AF=B9=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E5=92=8C=E5=8F=96=E6=B6=88=E8=81=8A=E5=A4=A9=E5=AE=A4=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=B6=88=E6=81=AF=E4=B8=8B=E8=BD=BD=E7=8A=B6=E6=80=81?= =?UTF-8?q?=EF=BC=8CIM-5397?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/application/JGApplication.java | 2 ++ .../chat/controller/ChatItemController.java | 31 ++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/chatapp/src/main/java/jiguang/chat/application/JGApplication.java b/chatapp/src/main/java/jiguang/chat/application/JGApplication.java index 817c7a52..ceb39158 100644 --- a/chatapp/src/main/java/jiguang/chat/application/JGApplication.java +++ b/chatapp/src/main/java/jiguang/chat/application/JGApplication.java @@ -102,6 +102,7 @@ public class JGApplication extends com.activeandroid.app.Application { private static final String JCHAT_CONFIGS = "JChat_configs"; public static String FILE_DIR = "sdcard/JChatDemo/recvFiles/"; public static String VIDEO_DIR = "sdcarVIDEOd/JChatDemo/sendFiles/"; + public static String THUMP_PICTURE_DIR; public static final String TARGET_ID = "targetId"; public static final String ATUSER = "atuser"; public static final String TARGET_APP_KEY = "targetAppKey"; @@ -128,6 +129,7 @@ public class JGApplication extends com.activeandroid.app.Application { public void onCreate() { super.onCreate(); context = getApplicationContext(); + THUMP_PICTURE_DIR = context.getFilesDir().getAbsolutePath() + "/JChatDemo"; StorageUtil.init(context, null); Fresco.initialize(getApplicationContext()); SDKInitializer.initialize(getApplicationContext()); diff --git a/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java b/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java index d98c6732..5d607f2f 100644 --- a/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java +++ b/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java @@ -13,10 +13,8 @@ import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; -import android.os.Environment; import android.support.v4.content.ContextCompat; import android.text.TextUtils; -import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; @@ -781,8 +779,29 @@ public void handleVideo(final Message msg, final ViewHolder holder, int position FileContent fileContent = (FileContent) msg.getContent(); String videoPath = fileContent.getLocalPath(); if (videoPath != null) { -// String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + msg.getServerMessageId(); - String thumbPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + msg.getServerMessageId(); + File dir = new File(JGApplication.THUMP_PICTURE_DIR); + if (!dir.exists()) { + dir.mkdirs(); + } + String thumbPath; + if (msg.getServerMessageId() == 0) { + switch (msg.getTargetType()) { + case single: + thumbPath = dir + "/" + msg.getTargetType() + "_" + ((UserInfo) msg.getTargetInfo()).getUserID() + "_" + msg.getId(); + break; + case group: + thumbPath = dir + "/" + msg.getTargetType() + "_" + ((GroupInfo) msg.getTargetInfo()).getGroupID() + "_" + msg.getId(); + break; + case chatroom: + thumbPath = dir + "/" + msg.getTargetType() + "_" + ((ChatRoomInfo) msg.getTargetInfo()).getRoomID() + "_" + msg.getId(); + break; + default: + Picasso.with(mContext).load(R.drawable.video_not_found).into(holder.picture); + return; + } + } else { + thumbPath = dir + "/" + msg.getServerMessageId(); + } String path = BitmapDecoder.extractThumbnail(videoPath, thumbPath); setPictureScale(null, msg, path, holder.picture); Picasso.with(mContext).load(new File(path)).into(holder.picture); @@ -1016,7 +1035,9 @@ public void onProgressUpdate(double v) { case receive_success: holder.progressTv.setVisibility(View.GONE); holder.contentLl.setBackground(mContext.getDrawable(R.drawable.jmui_msg_receive_bg)); - holder.fileLoad.setText("已下载"); + if (mConv.getType() != ConversationType.chatroom) { + holder.fileLoad.setText("已下载"); + } break; } } From a5772a8db9c6b86ea38cac93ca6f7956269ba34d Mon Sep 17 00:00:00 2001 From: jinfeng Date: Tue, 21 May 2019 15:02:35 +0800 Subject: [PATCH 05/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=89=E6=98=9F?= =?UTF-8?q?=E6=89=8B=E6=9C=BA=E6=8B=8D=E7=85=A7=E6=97=B6=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E6=97=8B=E8=BD=AC=E9=97=AE=E9=A2=98=EF=BC=8CIM-5397?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../photovideo/takevideo/utils/FileUtils.java | 123 +++++++++++++++++- 1 file changed, 121 insertions(+), 2 deletions(-) diff --git a/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/utils/FileUtils.java b/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/utils/FileUtils.java index cece39af..62db9ca7 100755 --- a/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/utils/FileUtils.java +++ b/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/utils/FileUtils.java @@ -8,6 +8,7 @@ import android.os.Environment; import android.os.StatFs; import android.text.TextUtils; +import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.Closeable; @@ -22,6 +23,7 @@ public class FileUtils { + private static final String TAG = FileUtils.class.getSimpleName(); /** * 随机命名 */ @@ -143,13 +145,17 @@ public static String getUploadVideoFile(Context context) { */ public static boolean savePhoto(String photoPath, byte[] data, boolean isFrontFacing) { if (photoPath != null && data != null) { + int degree = getOrientation(data); FileOutputStream fos = null; try { Bitmap preBitmap = compressBitmap(data, MAX_WIDTH, MAX_HEIGHT); + Matrix matrix = new Matrix(); + matrix.postRotate(degree); if (isFrontFacing) { - Matrix matrix = new Matrix(); matrix.postScale(1, -1); - Bitmap newBitmap = Bitmap.createBitmap(preBitmap, 0, 0, preBitmap.getWidth(), preBitmap.getHeight(), matrix, true); + } + Bitmap newBitmap = Bitmap.createBitmap(preBitmap, 0, 0, preBitmap.getWidth(), preBitmap.getHeight(), matrix, true); + if (preBitmap != newBitmap) { preBitmap.recycle(); preBitmap = newBitmap; } @@ -360,4 +366,117 @@ public static boolean writeFile(String str, File file, boolean append) { return false; } + public static int getOrientation(byte[] jpeg) { + if (jpeg == null) { + return 0; + } + + int offset = 0; + int length = 0; + + // ISO/IEC 10918-1:1993(E) + while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) { + int marker = jpeg[offset] & 0xFF; + + // Check if the marker is a padding. + if (marker == 0xFF) { + continue; + } + offset++; + + // Check if the marker is SOI or TEM. + if (marker == 0xD8 || marker == 0x01) { + continue; + } + // Check if the marker is EOI or SOS. + if (marker == 0xD9 || marker == 0xDA) { + break; + } + + // Get the length and check if it is reasonable. + length = pack(jpeg, offset, 2, false); + if (length < 2 || offset + length > jpeg.length) { + Log.e("69523", "Invalid length"); + return 0; + } + + // Break if the marker is EXIF in APP1. + if (marker == 0xE1 && length >= 8 && + pack(jpeg, offset + 2, 4, false) == 0x45786966 && + pack(jpeg, offset + 6, 2, false) == 0) { + offset += 8; + length -= 8; + break; + } + + // Skip other markers. + offset += length; + length = 0; + } + + // JEITA CP-3451 Exif Version 2.2 + if (length > 8) { + // Identify the byte order. + int tag = pack(jpeg, offset, 4, false); + if (tag != 0x49492A00 && tag != 0x4D4D002A) { + Log.e("69523", "Invalid byte order"); + return 0; + } + boolean littleEndian = (tag == 0x49492A00); + + // Get the offset and check if it is reasonable. + int count = pack(jpeg, offset + 4, 4, littleEndian) + 2; + if (count < 10 || count > length) { + Log.e(TAG, "Invalid offset"); + return 0; + } + offset += count; + length -= count; + + // Get the count and go through all the elements. + count = pack(jpeg, offset - 2, 2, littleEndian); + while (count-- > 0 && length >= 12) { + // Get the tag and check if it is orientation. + tag = pack(jpeg, offset, 2, littleEndian); + if (tag == 0x0112) { + // We do not really care about type and count, do we? + int orientation = pack(jpeg, offset + 8, 2, littleEndian); + switch (orientation) { + case 1: + return 0; + case 3: + return 180; + case 6: + return 90; + case 8: + return 270; + } + Log.i(TAG, "Unsupported orientation"); + return 0; + } + offset += 12; + length -= 12; + } + } + + Log.i(TAG, "Orientation not found"); + return 0; + } + + private static int pack(byte[] bytes, int offset, int length, + boolean littleEndian) { + int step = 1; + if (littleEndian) { + offset += length - 1; + step = -1; + } + + int value = 0; + while (length-- > 0) { + value = (value << 8) | (bytes[offset] & 0xFF); + offset += step; + } + return value; + } + } From 7e7d696805d1fa0f4f5eccd814e55f555f7f9793 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Tue, 21 May 2019 16:04:43 +0800 Subject: [PATCH 06/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E5=88=97=E8=A1=A8=E7=95=8C=E9=9D=A2=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E7=AE=A1=E7=90=86=E5=91=98=E8=AF=A6=E7=BB=86?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E9=97=AE=E9=A2=98=EF=BC=8CIM-5424?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/activity/ChatRoomKeeperActivity.java | 1 + .../adapter/ChatRoomKeeperListAdapter.java | 22 ++++++++++++++++++- .../main/res/layout/item_chat_room_keeper.xml | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatRoomKeeperActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomKeeperActivity.java index 14c61093..5fda44c2 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/ChatRoomKeeperActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomKeeperActivity.java @@ -88,6 +88,7 @@ public void gotResult(int i, String s, List userInfos) { } mAdapter = new ChatRoomKeeperListAdapter(ChatRoomKeeperActivity.this, mShowKeeperList, roomID, isOwner); mLvKeeper.setAdapter(mAdapter); + mLvKeeper.setOnItemClickListener(mAdapter); loadingDialog.dismiss(); } else { loadingDialog.dismiss(); diff --git a/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java index 5db22187..e74f304a 100644 --- a/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java @@ -2,10 +2,12 @@ import android.app.Dialog; import android.content.Context; +import android.content.Intent; import android.graphics.Bitmap; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; @@ -15,14 +17,18 @@ import java.util.List; import cn.jpush.im.android.api.ChatRoomManager; +import cn.jpush.im.android.api.JMessageClient; import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback; import cn.jpush.im.android.api.model.UserInfo; import cn.jpush.im.api.BasicCallback; import jiguang.chat.R; import jiguang.chat.activity.ChatRoomKeeperActivity; +import jiguang.chat.activity.GroupUserInfoActivity; +import jiguang.chat.activity.PersonalActivity; +import jiguang.chat.application.JGApplication; import jiguang.chat.utils.DialogCreator; -public class ChatRoomKeeperListAdapter extends BaseAdapter { +public class ChatRoomKeeperListAdapter extends BaseAdapter implements AdapterView.OnItemClickListener { private List keepers; private Context context; private LayoutInflater mInflater; @@ -96,6 +102,20 @@ public void gotResult(int i, String s, Bitmap bitmap) { return convertView; } + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Intent intent = new Intent(); + if (keepers.get(position).data.getUserID() == JMessageClient.getMyInfo().getUserID()) { + intent.setClass(context, PersonalActivity.class); + } else { + intent.setClass(context, GroupUserInfoActivity.class); + intent.putExtra(GroupUserInfoActivity.IS_FROM_GROUP, false); + intent.putExtra(JGApplication.NAME, keepers.get(position).data != null ? keepers.get(position).data.getUserName() : ""); + intent.putExtra(JGApplication.TARGET_APP_KEY, keepers.get(position).data != null ? keepers.get(position).data.getAppKey() : ""); + } + context.startActivity(intent); + } + class ViewHolder { ImageView iv_keeperAvatar; TextView tv_keeperName; diff --git a/chatapp/src/main/res/layout/item_chat_room_keeper.xml b/chatapp/src/main/res/layout/item_chat_room_keeper.xml index 7225c78d..d6a7b30a 100644 --- a/chatapp/src/main/res/layout/item_chat_room_keeper.xml +++ b/chatapp/src/main/res/layout/item_chat_room_keeper.xml @@ -37,6 +37,7 @@ android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_centerVertical="true" + android:focusable="false" android:background="@drawable/jmui_remove_btn_bg" android:padding="10dp" android:text = "移除" From 5cc0fa34f2056b34e8d71bd5cf34868d0ff393d2 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Tue, 21 May 2019 17:52:50 +0800 Subject: [PATCH 07/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=95=E8=81=8A?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E6=9A=82=E6=97=B6=E7=BE=A4=E7=BB=84=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E5=B1=9E=E6=80=A7=E9=97=AE=E9=A2=98=EF=BC=8CIM-5432?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/controller/ChatDetailController.java | 1 - .../jiguang/chat/view/ChatDetailView.java | 20 +++++++++---------- .../main/res/layout/activity_chat_detail.xml | 11 +++++++--- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/chatapp/src/main/java/jiguang/chat/controller/ChatDetailController.java b/chatapp/src/main/java/jiguang/chat/controller/ChatDetailController.java index 59f05f8c..afdfda79 100644 --- a/chatapp/src/main/java/jiguang/chat/controller/ChatDetailController.java +++ b/chatapp/src/main/java/jiguang/chat/controller/ChatDetailController.java @@ -186,7 +186,6 @@ public void initData() { mChatDetailView.setAdapter(mGridAdapter); // 设置单聊界面 mChatDetailView.setSingleView(mUserInfo.isFriend()); - mChatDetailView.dismissAllMembersBtn(); mChatDetailView.isLoadMoreShow(false); JMessageClient.getUserInfo(mTargetId, new GetUserInfoCallback() { diff --git a/chatapp/src/main/java/jiguang/chat/view/ChatDetailView.java b/chatapp/src/main/java/jiguang/chat/view/ChatDetailView.java index fb3eef62..e80289a5 100644 --- a/chatapp/src/main/java/jiguang/chat/view/ChatDetailView.java +++ b/chatapp/src/main/java/jiguang/chat/view/ChatDetailView.java @@ -25,8 +25,6 @@ public class ChatDetailView extends LinearLayout { private LinearLayout mGroupDescLL; - private View mSplitLine1; - private View mSplitLine2; private LinearLayout mGroupNameLL; private LinearLayout mMyNameLL; private LinearLayout mGroupNumLL; @@ -67,8 +65,6 @@ public ChatDetailView(Context context, AttributeSet attrs) { public void initModule() { mGroupDescLL = (LinearLayout) findViewById(R.id.group_desc_ll); mGroupDesc = (TextView) findViewById(R.id.chat_detail_group_desc); - mSplitLine1 = findViewById(R.id.all_member_split_line1); - mSplitLine2 = findViewById(R.id.all_member_split_line2); mGroupNameLL = (LinearLayout) findViewById(R.id.group_name_ll); mGroupAvatarLL = (RelativeLayout) findViewById(R.id.rl_groupAvatar); mIv_groupAvatar = (ImageView) findViewById(R.id.iv_groupAvatar); @@ -169,10 +165,20 @@ public void setSingleView(boolean friend) { mDetailAddFriend.setVisibility(VISIBLE); mDelGroupBtn.setVisibility(GONE); } + mGroupDescLL.setVisibility(View.GONE); mGroupNameLL.setVisibility(View.GONE); mGroupAvatarLL.setVisibility(View.GONE); mGroupNumLL.setVisibility(View.GONE); mMyNameLL.setVisibility(View.GONE); + findViewById(R.id.group_id).setVisibility(View.GONE); + findViewById(R.id.group_type).setVisibility(View.GONE); + findViewById(R.id.chat_silence).setVisibility(View.GONE); + findViewById(R.id.single_chat_remove_1).setVisibility(View.GONE); + findViewById(R.id.single_chat_remove_2).setVisibility(View.GONE); + findViewById(R.id.single_chat_remove_3).setVisibility(View.GONE); + findViewById(R.id.single_chat_remove_4).setVisibility(View.GONE); + findViewById(R.id.single_chat_remove_5).setVisibility(View.GONE); + findViewById(R.id.single_chat_remove_6).setVisibility(View.GONE); mDelGroupBtn.setText("删除好友"); } @@ -189,12 +195,6 @@ public void setGroupDesc(String desc) { mGroupDesc.setText(desc); } - public void dismissAllMembersBtn() { - mSplitLine1.setVisibility(View.GONE); - mSplitLine2.setVisibility(View.GONE); - mGroupDescLL.setVisibility(View.GONE); - } - public void initNoDisturb(int status) { mNoDisturbBtn.setChecked(status == 1); } diff --git a/chatapp/src/main/res/layout/activity_chat_detail.xml b/chatapp/src/main/res/layout/activity_chat_detail.xml index a713b7f6..814a1068 100644 --- a/chatapp/src/main/res/layout/activity_chat_detail.xml +++ b/chatapp/src/main/res/layout/activity_chat_detail.xml @@ -74,7 +74,6 @@ @@ -103,7 +102,7 @@ @@ -128,7 +127,7 @@ @@ -181,11 +180,13 @@ @@ -258,6 +262,7 @@ From 7a78bf2dabe244ac4d1c67c706d0509134cb1680 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 10:23:52 +0800 Subject: [PATCH 08/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=9C=AA=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8CIM-5433?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/activity/fragment/ConversationListFragment.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/ConversationListFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/ConversationListFragment.java index 6bf44c25..18d3ed51 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/fragment/ConversationListFragment.java +++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/ConversationListFragment.java @@ -21,6 +21,8 @@ import android.widget.PopupWindow; import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import cn.jpush.im.android.api.JMessageClient; import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback; @@ -68,6 +70,9 @@ public class ConversationListFragment extends BaseFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().register(this); + } isCreate = true; mContext = this.getActivity(); @@ -267,7 +272,8 @@ public void run() { } } - public void onEventMainThread(Event event) { + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEvent(Event event) { ; switch (event.getType()) { case createConversation: Conversation conv = event.getConversation(); @@ -340,5 +346,4 @@ public void sortConvList() { mConvListController.getAdapter().sortConvList(); } } - } From cb84bc64edadb00699006be06b3595c73f15e0e6 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 11:21:49 +0800 Subject: [PATCH 09/23] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E8=81=8A=E5=A4=A9=E5=AE=A4=E6=97=B6=E7=9A=84=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E3=80=82IM-5390?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/jiguang/chat/controller/ChatRoomController.java | 5 +++++ chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java b/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java index 921a9935..9c702e4c 100644 --- a/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java +++ b/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java @@ -58,6 +58,7 @@ public void gotResult(int i, String s, List result) { } chatRoomAdapter = new ChatRoomAdapter(mContext, chatRoomInfos, mChatRoomView); mChatRoomView.setChatRoomAdapter(chatRoomAdapter); + mChatRoomView.setNullChatRoom(chatRoomInfos.size() == 0); } }); } @@ -86,12 +87,14 @@ public void onClick(View v) { @Override public void onRefresh(@NonNull RefreshLayout refreshLayout) { + mChatRoomView.setNullChatRoom(false); ChatRoomManager.getChatRoomListByApp(0, PAGE_COUNT, new RequestCallback>() { @Override public void gotResult(int i, String s, List result) { if (i == 0) { chatRoomInfos.clear(); chatRoomInfos.addAll(result); + mChatRoomView.setNullChatRoom(chatRoomInfos.size() == 0); if (chatRoomAdapter != null) { chatRoomAdapter.notifyDataSetChanged(); } @@ -105,11 +108,13 @@ public void gotResult(int i, String s, List result) { @Override public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + mChatRoomView.setNullChatRoom(false); ChatRoomManager.getChatRoomListByApp(chatRoomInfos.size(), PAGE_COUNT, new RequestCallback>() { @Override public void gotResult(int i, String s, List result) { if (i == 0) { chatRoomInfos.addAll(result); + mChatRoomView.setNullChatRoom(chatRoomInfos.size() == 0); if (chatRoomAdapter != null) { chatRoomAdapter.notifyDataSetChanged(); } diff --git a/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java b/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java index bd10a78d..9d96e117 100644 --- a/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java +++ b/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java @@ -21,13 +21,14 @@ * Created by ${chenyn} on 2017/10/31. */ -public class ChatRoomView extends LinearLayout{ +public class ChatRoomView extends LinearLayout { private ChatRoomController mListener; private Context mContext; private ListView mChatRoomListView; private LayoutInflater mInflater; private LinearLayout mSearch_title; private SmartRefreshLayout smartRefreshLayout; + private TextView mNullChatRoom; public ChatRoomView(Context context) { super(context); @@ -48,6 +49,7 @@ public void initModule() { mChatRoomListView = findViewById(R.id.lv_chatRoom); mChatRoomListView.addHeaderView(view); smartRefreshLayout = findViewById(R.id.refreshLayout); + mNullChatRoom = findViewById(R.id.null_chatRoom); } public void setListener(ChatRoomController listener) { @@ -70,4 +72,8 @@ public void setOnLoadMoreListener(OnLoadMoreListener loadMoreListener) { smartRefreshLayout.setOnLoadMoreListener(loadMoreListener); } + public void setNullChatRoom(boolean isNullChatRoom) { + mNullChatRoom.setVisibility(isNullChatRoom ? VISIBLE : GONE); + } + } From edb91c378e4865ef171dbcc19325674cabcd1c5e Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 13:22:21 +0800 Subject: [PATCH 10/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E8=81=8A=E5=A4=A9=E5=AE=A4=E6=97=B6=E8=BE=93=E5=85=A5=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E5=AE=A4ID=E8=BF=87=E9=95=BF=E9=80=A0=E6=88=90?= =?UTF-8?q?=E7=9A=84=E5=B4=A9=E6=BA=83=E9=97=AE=E9=A2=98=EF=BC=8CIM-5391?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/activity/SearchChatRoomActivity.java | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java index 58295877..ad07ee0e 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java @@ -69,20 +69,25 @@ private void initData() { mTv_search.setOnClickListener(v -> { if (!TextUtils.isEmpty(mSearchEditText.getText())) { String roomId = mSearchEditText.getText().toString().trim(); - ChatRoomManager.getChatRoomInfos(Collections.singleton(Long.parseLong(roomId)), new RequestCallback>() { - @Override - public void gotResult(int i, String s, List chatRoomInfos) { - if (i == 0) { - mRoomID = chatRoomInfos.get(0).getRoomID(); - mLl_chatRoomItem.setVisibility(View.VISIBLE); - mTv_chatRoomDesc.setText(chatRoomInfos.get(0).getDescription()); - mTv_chatRoomName.setText(chatRoomInfos.get(0).getName()); - }else { - mLl_chatRoomItem.setVisibility(View.GONE); - Toast.makeText(SearchChatRoomActivity.this, "搜索的聊天室不存在", Toast.LENGTH_SHORT).show(); + try { + long id = Long.parseLong(roomId); + ChatRoomManager.getChatRoomInfos(Collections.singleton(id), new RequestCallback>() { + @Override + public void gotResult(int i, String s, List chatRoomInfos) { + if (i == 0) { + mRoomID = chatRoomInfos.get(0).getRoomID(); + mLl_chatRoomItem.setVisibility(View.VISIBLE); + mTv_chatRoomDesc.setText(chatRoomInfos.get(0).getDescription()); + mTv_chatRoomName.setText(chatRoomInfos.get(0).getName()); + }else { + mLl_chatRoomItem.setVisibility(View.GONE); + Toast.makeText(SearchChatRoomActivity.this, "搜索的聊天室不存在", Toast.LENGTH_SHORT).show(); + } } - } - }); + }); + } catch (NumberFormatException e) { + Toast.makeText(SearchChatRoomActivity.this, "搜索的聊天室不存在", Toast.LENGTH_SHORT).show(); + } } }); From 81be817e254ddbe41b555f5fe7a9a5615e904349 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 13:35:43 +0800 Subject: [PATCH 11/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BD=95=E5=88=B6?= =?UTF-8?q?=E5=B0=8F=E8=A7=86=E9=A2=91=E5=81=B6=E5=85=88=E7=9A=84=E5=B4=A9?= =?UTF-8?q?=E6=BA=83=E9=97=AE=E9=A2=98=EF=BC=8CIM-5403?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../takevideo/camera/CameraManager.java | 1009 +++++++++-------- 1 file changed, 506 insertions(+), 503 deletions(-) diff --git a/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/camera/CameraManager.java b/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/camera/CameraManager.java index 91435b90..91edf647 100755 --- a/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/camera/CameraManager.java +++ b/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/camera/CameraManager.java @@ -1,503 +1,506 @@ -package jiguang.chat.utils.photovideo.takevideo.camera; - -import android.app.Application; -import android.content.Context; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.SurfaceTexture; -import android.hardware.Camera; -import android.media.CamcorderProfile; -import android.media.MediaRecorder; -import android.widget.Toast; - -import java.util.ArrayList; -import java.util.List; - -import jiguang.chat.utils.photovideo.takevideo.utils.LogUtils; - - -/** - * 相机管理类 - */ - -public final class CameraManager { - - private Application context; - /** - * camera - */ - private Camera mCamera; - /** - * 视频录制 - */ - private MediaRecorder mMediaRecorder; - /** - * 相机闪光状态 - */ - private int cameraFlash; - /** - * 前后置状态 - */ - private int cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK; - /** - * 是否支持前置摄像,是否支持闪光 - */ - private boolean isSupportFrontCamera, isSupportFlashCamera; - /** - * 录制视频的相关参数 - */ - private CamcorderProfile mProfile; - /** - * 0为拍照, 1为录像 - */ - private int cameraType; - - private CameraManager(Application context) { - this.context = context; - isSupportFrontCamera = CameraUtils.isSupportFrontCamera(); - isSupportFlashCamera = CameraUtils.isSupportFlashCamera(context); - if (isSupportFrontCamera) { - cameraFacing = CameraUtils.getCameraFacing(context, Camera.CameraInfo.CAMERA_FACING_BACK); - } - if (isSupportFlashCamera) { - cameraFlash = CameraUtils.getCameraFlash(context); - } - } - - private static CameraManager INSTANCE; - - public static CameraManager getInstance(Application context) { - if (INSTANCE == null) { - synchronized (CameraManager.class) { - if (INSTANCE == null) { - INSTANCE = new CameraManager(context); - } - } - } - return INSTANCE; - } - - /** - * 打开camera - */ - public void openCamera(Context context, SurfaceTexture surfaceTexture, int width, int height) { - if (mCamera == null) { - try { - mCamera = Camera.open(cameraFacing);//打开当前选中的摄像头 - mProfile = CamcorderProfile.get(cameraFacing, CamcorderProfile.QUALITY_HIGH); - mCamera.setDisplayOrientation(90);//默认竖直拍照 - mCamera.setPreviewTexture(surfaceTexture); - initCameraParameters(cameraFacing, width, height); - mCamera.startPreview(); - } catch (Exception e) { - if (mCamera != null) { - mCamera.release(); - mCamera = null; - } - } - } - } - - - /** - * 开启预览,前提是camera初始化了 - */ - public void restartPreview() { - if (mCamera == null) return; - try { - Camera.Parameters parameters = mCamera.getParameters(); - int zoom = parameters.getZoom(); - if (zoom > 0) { - parameters.setZoom(0); - mCamera.setParameters(parameters); - } - mCamera.startPreview(); - } catch (Exception e) { - LogUtils.i(e); - if (mCamera != null) { - mCamera.release(); - mCamera = null; - } - } - } - - private void initCameraParameters(int cameraId, int width, int height) { - Camera.Parameters parameters = mCamera.getParameters(); - if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) { - List focusModes = parameters.getSupportedFocusModes(); - if (focusModes != null) { - if (cameraType == 0) { - if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); - } - } else { - if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); - } - } - } - } - parameters.setRotation(90);//设置旋转代码, - switch (cameraFlash) { - case 0: - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); - break; - case 1: - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); - break; - case 2: - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); - break; - } - List pictureSizes = parameters.getSupportedPictureSizes(); - List previewSizes = parameters.getSupportedPreviewSizes(); - if (!isEmpty(pictureSizes) && !isEmpty(previewSizes)) { - /*for (Camera.Size size : pictureSizes) { - LogUtils.i("pictureSize " + size.width + " " + size.height); - } - for (Camera.Size size : pictureSizes) { - LogUtils.i("previewSize " + size.width + " " + size.height); - }*/ - Camera.Size optimalPicSize = getOptimalSize(pictureSizes, width, height); - Camera.Size optimalPreSize = getOptimalSize(previewSizes, width, height); - LogUtils.i("TextureSize " + width + " " + height + " optimalSize pic " + optimalPicSize.width + " " + optimalPicSize.height + " pre " + optimalPreSize.width + " " + optimalPreSize.height); - parameters.setPictureSize(optimalPicSize.width, optimalPicSize.height); - parameters.setPreviewSize(optimalPreSize.width, optimalPreSize.height); - mProfile.videoFrameWidth = optimalPreSize.width; - mProfile.videoFrameHeight = optimalPreSize.height; - mProfile.videoBitRate = 5000000;//此参数主要决定视频拍出大小 - } - mCamera.setParameters(parameters); - } - - /** - * 释放摄像头 - */ - public void closeCamera() { - this.cameraType = 0; - if (mCamera != null) { - try { - mCamera.stopPreview(); - mCamera.release(); - mCamera = null; - } catch (Exception e) { - LogUtils.i(e); - if (mCamera != null) { - mCamera.release(); - mCamera = null; - } - } - } - } - - /** - * 集合不为空 - * - * @param list - * @param - * @return - */ - private boolean isEmpty(List list) { - return list == null || list.isEmpty(); - } - - /** - * 获取最佳预览相机Size参数 - * - * @return - */ - private Camera.Size getOptimalSize(List sizes, int w, int h) { - Camera.Size optimalSize = null; - float targetRadio = h / (float) w; - float optimalDif = Float.MAX_VALUE; //最匹配的比例 - int optimalMaxDif = Integer.MAX_VALUE;//最优的最大值差距 - for (Camera.Size size : sizes) { - float newOptimal = size.width / (float) size.height; - float newDiff = Math.abs(newOptimal - targetRadio); - if (newDiff < optimalDif) { //更好的尺寸 - optimalDif = newDiff; - optimalSize = size; - optimalMaxDif = Math.abs(h - size.width); - } else if (newDiff == optimalDif) {//更好的尺寸 - int newOptimalMaxDif = Math.abs(h - size.width); - if (newOptimalMaxDif < optimalMaxDif) { - optimalDif = newDiff; - optimalSize = size; - optimalMaxDif = newOptimalMaxDif; - } - } - } - return optimalSize; - } - - /** - * 缩放 - * - * @param isZoomIn - */ - public void handleZoom(boolean isZoomIn) { - if (mCamera == null) return; - Camera.Parameters params = mCamera.getParameters(); - if (params == null) return; - if (params.isZoomSupported()) { - int maxZoom = params.getMaxZoom(); - int zoom = params.getZoom(); - if (isZoomIn && zoom < maxZoom) { - zoom++; - } else if (zoom > 0) { - zoom--; - } - params.setZoom(zoom); - mCamera.setParameters(params); - } else { - LogUtils.i("zoom not supported"); - } - } - - /** - * 更换前后置摄像 - */ - public void changeCameraFacing(Context context, SurfaceTexture surfaceTexture, int width, int height) { - if (isSupportFrontCamera) { - Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); - int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数 - for (int i = 0; i < cameraCount; i++) { - Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息 - if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { //现在是后置,变更为前置 - if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位为前置 - closeCamera(); - cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK; - CameraUtils.setCameraFacing(context, cameraFacing); - openCamera(context, surfaceTexture, width, height); - break; - } - } else {//现在是前置, 变更为后置 - if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位 - closeCamera(); - cameraFacing = Camera.CameraInfo.CAMERA_FACING_FRONT; - CameraUtils.setCameraFacing(context, cameraFacing); - openCamera(context, surfaceTexture, width, height); - break; - } - } - } - } else { //不支持摄像机 - Toast.makeText(context, "您的手机不支持前置摄像", Toast.LENGTH_SHORT).show(); - } - } - - /** - * 改变闪光状态 - */ - public void changeCameraFlash(SurfaceTexture surfaceTexture, int width, int height) { - if (!isSupportFlashCamera) { - Toast.makeText(context, "您的手机不支闪光", Toast.LENGTH_SHORT).show(); - return; - } - if (mCamera != null) { - Camera.Parameters parameters = mCamera.getParameters(); - if (parameters != null) { - int newState = cameraFlash; - switch (cameraFlash) { - case 0: //自动 - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); - newState = 1; - break; - case 1://open - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); - newState = 2; - break; - case 2: //close - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); - newState = 0; - break; - } - cameraFlash = newState; - CameraUtils.setCameraFlash(context, newState); - mCamera.setParameters(parameters); - } - } - } - - /** - * 拍照 - */ - public void takePhoto(Camera.PictureCallback callback) { - if (mCamera != null) { - try { - mCamera.takePicture(null, null, callback); - } catch (Exception e) { - Toast.makeText(context, "拍摄失败", Toast.LENGTH_SHORT).show(); - } - } - } - - - /** - * 开始录制视频 - */ - public void startMediaRecord(String savePath) { - if (mCamera == null || mProfile == null) return; - mCamera.unlock(); - if (mMediaRecorder == null) { - mMediaRecorder = new MediaRecorder(); - mMediaRecorder.setOrientationHint(90); - } - if (isCameraFrontFacing()) { - mMediaRecorder.setOrientationHint(270); - } - mMediaRecorder.reset(); - mMediaRecorder.setCamera(mCamera); - mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); - mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); - mMediaRecorder.setProfile(mProfile); - mMediaRecorder.setOutputFile(savePath); - try { - mMediaRecorder.prepare(); - mMediaRecorder.start(); - } catch (Exception e) { - e.printStackTrace(); - - } - } - - /** - * 停止录制 - */ - public void stopMediaRecord() { - this.cameraType = 0; - stopRecorder(); - releaseMediaRecorder(); - } - - private void releaseMediaRecorder() { - if (mMediaRecorder != null) { - try { - mMediaRecorder.reset(); - mMediaRecorder.release(); - mMediaRecorder = null; - mCamera.lock(); - } catch (Exception e) { - e.printStackTrace(); - LogUtils.i(e); - } - } - } - - private void stopRecorder() { - if (mMediaRecorder != null) { - try { - mMediaRecorder.stop(); - } catch (Exception e) { - e.printStackTrace(); - LogUtils.i(e); - } - - } - } - - public boolean isSupportFrontCamera() { - return isSupportFrontCamera; - } - - public boolean isSupportFlashCamera() { - return isSupportFlashCamera; - } - - public boolean isCameraFrontFacing() { - return cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT; - } - - /** - * 设置对焦类型 - * - * @param cameraType - */ - public void setCameraType(int cameraType) { - this.cameraType = cameraType; - if (mCamera != null) {//拍摄视频时 - if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) { - Camera.Parameters parameters = mCamera.getParameters(); - List focusModes = parameters.getSupportedFocusModes(); - if (focusModes != null) { - if (cameraType == 0) { - if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); - } - } else { - if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); - } - } - } - } - } - } - - public int getCameraFlash() { - return cameraFlash; - } - - /** - * 对焦 - * - * @param x - * @param y - */ - public void handleFocusMetering(float x, float y) { - Camera.Parameters params = mCamera.getParameters(); - Camera.Size previewSize = params.getPreviewSize(); - Rect focusRect = calculateTapArea(x, y, 1f, previewSize); - Rect meteringRect = calculateTapArea(x, y, 1.5f, previewSize); - mCamera.cancelAutoFocus(); - - if (params.getMaxNumFocusAreas() > 0) { - List focusAreas = new ArrayList<>(); - focusAreas.add(new Camera.Area(focusRect, 1000)); - params.setFocusAreas(focusAreas); - } else { - LogUtils.i("focus areas not supported"); - } - if (params.getMaxNumMeteringAreas() > 0) { - List meteringAreas = new ArrayList<>(); - meteringAreas.add(new Camera.Area(meteringRect, 1000)); - params.setMeteringAreas(meteringAreas); - } else { - LogUtils.i("metering areas not supported"); - } - final String currentFocusMode = params.getFocusMode(); - params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); - mCamera.setParameters(params); - - mCamera.autoFocus(new Camera.AutoFocusCallback() { - @Override - public void onAutoFocus(boolean success, Camera camera) { - Camera.Parameters params = camera.getParameters(); - params.setFocusMode(currentFocusMode); - camera.setParameters(params); - } - }); - } - - private Rect calculateTapArea(float x, float y, float coefficient, Camera.Size previewSize) { - float focusAreaSize = 300; - int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue(); - int centerX = (int) (x / previewSize.width - 1000); - int centerY = (int) (y / previewSize.height - 1000); - int left = clamp(centerX - areaSize / 2, -1000, 1000); - int top = clamp(centerY - areaSize / 2, -1000, 1000); - RectF rectF = new RectF(left, top, left + areaSize, top + areaSize); - return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom)); - } - - private int clamp(int x, int min, int max) { - if (x > max) { - return max; - } - if (x < min) { - return min; - } - return x; - } - -} +package jiguang.chat.utils.photovideo.takevideo.camera; + +import android.app.Application; +import android.content.Context; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.SurfaceTexture; +import android.hardware.Camera; +import android.media.CamcorderProfile; +import android.media.MediaRecorder; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +import jiguang.chat.utils.photovideo.takevideo.utils.LogUtils; + + +/** + * 相机管理类 + */ + +public final class CameraManager { + + private Application context; + /** + * camera + */ + private Camera mCamera; + /** + * 视频录制 + */ + private MediaRecorder mMediaRecorder; + /** + * 相机闪光状态 + */ + private int cameraFlash; + /** + * 前后置状态 + */ + private int cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK; + /** + * 是否支持前置摄像,是否支持闪光 + */ + private boolean isSupportFrontCamera, isSupportFlashCamera; + /** + * 录制视频的相关参数 + */ + private CamcorderProfile mProfile; + /** + * 0为拍照, 1为录像 + */ + private int cameraType; + + private CameraManager(Application context) { + this.context = context; + isSupportFrontCamera = CameraUtils.isSupportFrontCamera(); + isSupportFlashCamera = CameraUtils.isSupportFlashCamera(context); + if (isSupportFrontCamera) { + cameraFacing = CameraUtils.getCameraFacing(context, Camera.CameraInfo.CAMERA_FACING_BACK); + } + if (isSupportFlashCamera) { + cameraFlash = CameraUtils.getCameraFlash(context); + } + } + + private static CameraManager INSTANCE; + + public static CameraManager getInstance(Application context) { + if (INSTANCE == null) { + synchronized (CameraManager.class) { + if (INSTANCE == null) { + INSTANCE = new CameraManager(context); + } + } + } + return INSTANCE; + } + + /** + * 打开camera + */ + public void openCamera(Context context, SurfaceTexture surfaceTexture, int width, int height) { + if (mCamera == null) { + try { + mCamera = Camera.open(cameraFacing);//打开当前选中的摄像头 + mProfile = CamcorderProfile.get(cameraFacing, CamcorderProfile.QUALITY_HIGH); + mCamera.setDisplayOrientation(90);//默认竖直拍照 + mCamera.setPreviewTexture(surfaceTexture); + initCameraParameters(cameraFacing, width, height); + mCamera.startPreview(); + } catch (Exception e) { + if (mCamera != null) { + mCamera.release(); + mCamera = null; + } + } + } + } + + + /** + * 开启预览,前提是camera初始化了 + */ + public void restartPreview() { + if (mCamera == null) return; + try { + Camera.Parameters parameters = mCamera.getParameters(); + int zoom = parameters.getZoom(); + if (zoom > 0) { + parameters.setZoom(0); + mCamera.setParameters(parameters); + } + mCamera.startPreview(); + } catch (Exception e) { + LogUtils.i(e); + if (mCamera != null) { + mCamera.release(); + mCamera = null; + } + } + } + + private void initCameraParameters(int cameraId, int width, int height) { + Camera.Parameters parameters = mCamera.getParameters(); + if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) { + List focusModes = parameters.getSupportedFocusModes(); + if (focusModes != null) { + if (cameraType == 0) { + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + } + } else { + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + } + } + } + } + parameters.setRotation(90);//设置旋转代码, + switch (cameraFlash) { + case 0: + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); + break; + case 1: + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); + break; + case 2: + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); + break; + } + List pictureSizes = parameters.getSupportedPictureSizes(); + List previewSizes = parameters.getSupportedPreviewSizes(); + if (!isEmpty(pictureSizes) && !isEmpty(previewSizes)) { + /*for (Camera.Size size : pictureSizes) { + LogUtils.i("pictureSize " + size.width + " " + size.height); + } + for (Camera.Size size : pictureSizes) { + LogUtils.i("previewSize " + size.width + " " + size.height); + }*/ + Camera.Size optimalPicSize = getOptimalSize(pictureSizes, width, height); + Camera.Size optimalPreSize = getOptimalSize(previewSizes, width, height); + LogUtils.i("TextureSize " + width + " " + height + " optimalSize pic " + optimalPicSize.width + " " + optimalPicSize.height + " pre " + optimalPreSize.width + " " + optimalPreSize.height); + parameters.setPictureSize(optimalPicSize.width, optimalPicSize.height); + parameters.setPreviewSize(optimalPreSize.width, optimalPreSize.height); + mProfile.videoFrameWidth = optimalPreSize.width; + mProfile.videoFrameHeight = optimalPreSize.height; + mProfile.videoBitRate = 5000000;//此参数主要决定视频拍出大小 + } + mCamera.setParameters(parameters); + } + + /** + * 释放摄像头 + */ + public void closeCamera() { + this.cameraType = 0; + if (mCamera != null) { + try { + mCamera.stopPreview(); + mCamera.release(); + mCamera = null; + } catch (Exception e) { + LogUtils.i(e); + if (mCamera != null) { + mCamera.release(); + mCamera = null; + } + } + } + } + + /** + * 集合不为空 + * + * @param list + * @param + * @return + */ + private boolean isEmpty(List list) { + return list == null || list.isEmpty(); + } + + /** + * 获取最佳预览相机Size参数 + * + * @return + */ + private Camera.Size getOptimalSize(List sizes, int w, int h) { + Camera.Size optimalSize = null; + float targetRadio = h / (float) w; + float optimalDif = Float.MAX_VALUE; //最匹配的比例 + int optimalMaxDif = Integer.MAX_VALUE;//最优的最大值差距 + for (Camera.Size size : sizes) { + float newOptimal = size.width / (float) size.height; + float newDiff = Math.abs(newOptimal - targetRadio); + if (newDiff < optimalDif) { //更好的尺寸 + optimalDif = newDiff; + optimalSize = size; + optimalMaxDif = Math.abs(h - size.width); + } else if (newDiff == optimalDif) {//更好的尺寸 + int newOptimalMaxDif = Math.abs(h - size.width); + if (newOptimalMaxDif < optimalMaxDif) { + optimalDif = newDiff; + optimalSize = size; + optimalMaxDif = newOptimalMaxDif; + } + } + } + return optimalSize; + } + + /** + * 缩放 + * + * @param isZoomIn + */ + public void handleZoom(boolean isZoomIn) { + if (mCamera == null) return; + Camera.Parameters params = mCamera.getParameters(); + if (params == null) return; + if (params.isZoomSupported()) { + int maxZoom = params.getMaxZoom(); + int zoom = params.getZoom(); + if (isZoomIn && zoom < maxZoom) { + zoom++; + } else if (zoom > 0) { + zoom--; + } + params.setZoom(zoom); + mCamera.setParameters(params); + } else { + LogUtils.i("zoom not supported"); + } + } + + /** + * 更换前后置摄像 + */ + public void changeCameraFacing(Context context, SurfaceTexture surfaceTexture, int width, int height) { + if (isSupportFrontCamera) { + Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); + int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数 + for (int i = 0; i < cameraCount; i++) { + Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息 + if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { //现在是后置,变更为前置 + if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位为前置 + closeCamera(); + cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK; + CameraUtils.setCameraFacing(context, cameraFacing); + openCamera(context, surfaceTexture, width, height); + break; + } + } else {//现在是前置, 变更为后置 + if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位 + closeCamera(); + cameraFacing = Camera.CameraInfo.CAMERA_FACING_FRONT; + CameraUtils.setCameraFacing(context, cameraFacing); + openCamera(context, surfaceTexture, width, height); + break; + } + } + } + } else { //不支持摄像机 + Toast.makeText(context, "您的手机不支持前置摄像", Toast.LENGTH_SHORT).show(); + } + } + + /** + * 改变闪光状态 + */ + public void changeCameraFlash(SurfaceTexture surfaceTexture, int width, int height) { + if (!isSupportFlashCamera) { + Toast.makeText(context, "您的手机不支闪光", Toast.LENGTH_SHORT).show(); + return; + } + if (mCamera != null) { + Camera.Parameters parameters = mCamera.getParameters(); + if (parameters != null) { + int newState = cameraFlash; + switch (cameraFlash) { + case 0: //自动 + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); + newState = 1; + break; + case 1://open + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); + newState = 2; + break; + case 2: //close + parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); + newState = 0; + break; + } + cameraFlash = newState; + CameraUtils.setCameraFlash(context, newState); + mCamera.setParameters(parameters); + } + } + } + + /** + * 拍照 + */ + public void takePhoto(Camera.PictureCallback callback) { + if (mCamera != null) { + try { + mCamera.takePicture(null, null, callback); + } catch (Exception e) { + Toast.makeText(context, "拍摄失败", Toast.LENGTH_SHORT).show(); + } + } + } + + + /** + * 开始录制视频 + */ + public void startMediaRecord(String savePath) { + if (mCamera == null || mProfile == null) return; + mCamera.unlock(); + if (mMediaRecorder == null) { + mMediaRecorder = new MediaRecorder(); + mMediaRecorder.setOrientationHint(90); + } + if (isCameraFrontFacing()) { + mMediaRecorder.setOrientationHint(270); + } + mMediaRecorder.reset(); + mMediaRecorder.setCamera(mCamera); + mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); + mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); + mMediaRecorder.setProfile(mProfile); + mMediaRecorder.setOutputFile(savePath); + try { + mMediaRecorder.prepare(); + mMediaRecorder.start(); + } catch (Exception e) { + e.printStackTrace(); + + } + } + + /** + * 停止录制 + */ + public void stopMediaRecord() { + this.cameraType = 0; + stopRecorder(); + releaseMediaRecorder(); + } + + private void releaseMediaRecorder() { + if (mMediaRecorder != null) { + try { + mMediaRecorder.reset(); + mMediaRecorder.release(); + mMediaRecorder = null; + mCamera.lock(); + } catch (Exception e) { + e.printStackTrace(); + LogUtils.i(e); + } + } + } + + private void stopRecorder() { + if (mMediaRecorder != null) { + try { + mMediaRecorder.stop(); + } catch (Exception e) { + e.printStackTrace(); + LogUtils.i(e); + } + + } + } + + public boolean isSupportFrontCamera() { + return isSupportFrontCamera; + } + + public boolean isSupportFlashCamera() { + return isSupportFlashCamera; + } + + public boolean isCameraFrontFacing() { + return cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT; + } + + /** + * 设置对焦类型 + * + * @param cameraType + */ + public void setCameraType(int cameraType) { + this.cameraType = cameraType; + if (mCamera != null) {//拍摄视频时 + if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) { + Camera.Parameters parameters = mCamera.getParameters(); + List focusModes = parameters.getSupportedFocusModes(); + if (focusModes != null) { + if (cameraType == 0) { + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + } + } else { + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) { + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + } + } + } + } + } + } + + public int getCameraFlash() { + return cameraFlash; + } + + /** + * 对焦 + * + * @param x + * @param y + */ + public void handleFocusMetering(float x, float y) { + if (mCamera == null) { // TODO:2019/05/22 使用三星手机发送小视频时会报空指针异常,这里先判断非空,后续查找原因 + return; + } + Camera.Parameters params = mCamera.getParameters(); + Camera.Size previewSize = params.getPreviewSize(); + Rect focusRect = calculateTapArea(x, y, 1f, previewSize); + Rect meteringRect = calculateTapArea(x, y, 1.5f, previewSize); + mCamera.cancelAutoFocus(); + + if (params.getMaxNumFocusAreas() > 0) { + List focusAreas = new ArrayList<>(); + focusAreas.add(new Camera.Area(focusRect, 1000)); + params.setFocusAreas(focusAreas); + } else { + LogUtils.i("focus areas not supported"); + } + if (params.getMaxNumMeteringAreas() > 0) { + List meteringAreas = new ArrayList<>(); + meteringAreas.add(new Camera.Area(meteringRect, 1000)); + params.setMeteringAreas(meteringAreas); + } else { + LogUtils.i("metering areas not supported"); + } + final String currentFocusMode = params.getFocusMode(); + params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + mCamera.setParameters(params); + + mCamera.autoFocus(new Camera.AutoFocusCallback() { + @Override + public void onAutoFocus(boolean success, Camera camera) { + Camera.Parameters params = camera.getParameters(); + params.setFocusMode(currentFocusMode); + camera.setParameters(params); + } + }); + } + + private Rect calculateTapArea(float x, float y, float coefficient, Camera.Size previewSize) { + float focusAreaSize = 300; + int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue(); + int centerX = (int) (x / previewSize.width - 1000); + int centerY = (int) (y / previewSize.height - 1000); + int left = clamp(centerX - areaSize / 2, -1000, 1000); + int top = clamp(centerY - areaSize / 2, -1000, 1000); + RectF rectF = new RectF(left, top, left + areaSize, top + areaSize); + return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom)); + } + + private int clamp(int x, int min, int max) { + if (x > max) { + return max; + } + if (x < min) { + return min; + } + return x; + } + +} From 3b7bbc44ce176a10d9ab9cafbab7f14d3fb68ffa Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 13:45:26 +0800 Subject: [PATCH 12/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=81=8A=E5=A4=A9=E5=AE=A4=E7=AE=A1=E7=90=86=E5=91=98=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2title=E4=B8=8D=E6=AD=A3=E7=A1=AE=E9=97=AE=E9=A2=98,IM-?= =?UTF-8?q?5408?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/jiguang/chat/activity/SearchForChatRoomActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java index cfa824e4..e6b2974e 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java @@ -62,7 +62,7 @@ protected void onCreate(Bundle savedInstanceState) { mIvClear = (ImageView) findViewById(R.id.iv_clear); mIvClear.setOnClickListener(this); - initTitle(true, true, "添加黑名单", "", false, ""); + initTitle(true, true, "添加管理员", "", false, ""); } @Override From a4560e6d42bb6f010e66718012ddde19bb805bc1 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 14:38:57 +0800 Subject: [PATCH 13/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E5=A4=B4=E5=83=8F=E9=94=99=E4=B9=B1=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8CIM-5410?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java index e74f304a..d8b0618f 100644 --- a/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java @@ -89,6 +89,7 @@ public void gotResult(int i, String s) { } else { holder = (ViewHolder) convertView.getTag(); } + holder.iv_keeperAvatar.setImageResource(R.drawable.rc_default_portrait); UserInfo userInfo = keepers.get(position).data; userInfo.getAvatarBitmap(new GetAvatarBitmapCallback() { @Override From e7554950accfd70e58b4be0323aded4b2248e446 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 14:41:49 +0800 Subject: [PATCH 14/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E8=81=8A=E5=A4=A9=E5=AE=A4=E6=8C=89=E9=92=AE=E4=B8=8D=E7=94=9F?= =?UTF-8?q?=E6=95=88=E9=97=AE=E9=A2=98,=20IM-5412?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/jiguang/chat/activity/SearchChatRoomActivity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java index ad07ee0e..6220e02e 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java @@ -88,6 +88,8 @@ public void gotResult(int i, String s, List chatRoomInfos) { } catch (NumberFormatException e) { Toast.makeText(SearchChatRoomActivity.this, "搜索的聊天室不存在", Toast.LENGTH_SHORT).show(); } + } else { + Toast.makeText(SearchChatRoomActivity.this, "请输入聊天室ID", Toast.LENGTH_SHORT).show(); } }); From eda8bbca3992dfb0de91a7d23f37b61b061efaef Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 14:45:05 +0800 Subject: [PATCH 15/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=AE=A4=E5=90=8D=E7=A7=B0=E5=B1=95=E7=A4=BA=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8CIM-5417?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chatapp/src/main/res/layout/activity_search_chat_room.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chatapp/src/main/res/layout/activity_search_chat_room.xml b/chatapp/src/main/res/layout/activity_search_chat_room.xml index c1655b65..87704c37 100644 --- a/chatapp/src/main/res/layout/activity_search_chat_room.xml +++ b/chatapp/src/main/res/layout/activity_search_chat_room.xml @@ -109,6 +109,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="聊天室名字" + android:ellipsize="end" + android:maxLines="1" android:textColor="#2C2C2C" android:textSize="16sp"/> From 3e79ce68d6ef4e7fadfd0ea65bbb73a8098d6ec1 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 15:29:24 +0800 Subject: [PATCH 16/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=AE=A4=E7=AE=A1=E7=90=86=E5=91=98=E5=A4=B4=E5=83=8F=E5=8C=BA?= =?UTF-8?q?=E5=9F=9F=E4=B8=8D=E8=83=BD=E8=B7=B3=E8=BD=AC=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8CIM-5419?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/jiguang/chat/activity/ChatRoomInfoActivity.java | 4 ++++ chatapp/src/main/res/layout/activity_chat_room_info.xml | 1 + 2 files changed, 5 insertions(+) diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatRoomInfoActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomInfoActivity.java index b43bd77a..50647b9d 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/ChatRoomInfoActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomInfoActivity.java @@ -98,6 +98,7 @@ public void onClick(View v) { }; exitDialog = DialogCreator.createBaseDialogWithTitle(ChatRoomInfoActivity.this, "确定退出聊天室", listener); exitDialog.show(); + break; default: break; } @@ -129,6 +130,9 @@ private void initData() { mTvChatRoomDesc = (TextView) findViewById(R.id.tv_chatRoomDesc); mTvChatRoomOwner = (TextView) findViewById(R.id.tv_chatRoomOwner); mGvChatRoomKeeper = (NoScrollGridView) findViewById(R.id.grid_chatRommKeeper); + mGvChatRoomKeeper.setClickable(false); + mGvChatRoomKeeper.setPressed(false); + mGvChatRoomKeeper.setEnabled(false); roomId = getIntent().getLongExtra("chatRoomId", 0); findViewById(R.id.ll_chat_room_name).setOnClickListener(this); findViewById(R.id.ll_chat_room_desc).setOnClickListener(this); diff --git a/chatapp/src/main/res/layout/activity_chat_room_info.xml b/chatapp/src/main/res/layout/activity_chat_room_info.xml index c32ea81c..8f0215aa 100644 --- a/chatapp/src/main/res/layout/activity_chat_room_info.xml +++ b/chatapp/src/main/res/layout/activity_chat_room_info.xml @@ -72,6 +72,7 @@ Date: Wed, 22 May 2019 15:40:22 +0800 Subject: [PATCH 17/23] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E5=A4=B1=E8=B4=A5=E6=97=B6=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=EF=BC=8CIM-5423?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/SearchForChatRoomActivity.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java index e6b2974e..04746eef 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java @@ -122,8 +122,9 @@ public void gotResult(int i, String s) { if (i == 0) { ToastUtil.shortToast(SearchForChatRoomActivity.this, "添加成功"); } else { - ToastUtil.shortToast(SearchForChatRoomActivity.this, "添加失败,code:" + i); + handleErrorCode(i); } + mSearch_result.setVisibility(View.GONE); } }); @@ -136,6 +137,20 @@ public void gotResult(int i, String s) { } } + private void handleErrorCode(int code) { + String result = "添加失败,code:" + code; + switch (code) { + case 7130004: + result = "添加失败,管理员人数已达上限"; + break; + case 7130006: + result = "添加失败,用户不在聊天室中"; + break; + default: + } + ToastUtil.shortToast(SearchForChatRoomActivity.this, result); + } + private class TextChange implements TextWatcher { @Override From 7afc2a408991a31064b3711a4f48256453b731d5 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 16:18:06 +0800 Subject: [PATCH 18/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E4=BC=9A=E8=AF=9D=E5=88=97=E8=A1=A8=E6=97=B6=E8=AF=AD=E9=9F=B3?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=BB=8D=E5=9C=A8=E6=92=AD=E6=94=BE=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=8CIM-5411?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/jiguang/chat/activity/ChatActivity.java | 3 +++ .../main/java/jiguang/chat/adapter/ChattingListAdapter.java | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java index 8383f5aa..b06b08b1 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java @@ -526,6 +526,9 @@ public void onBackPressed() { private void returnBtn() { mConv.resetUnreadCount(); dismissSoftInput(); + if (mChatAdapter != null) { + mChatAdapter.stopMediaPlayer(); + } JMessageClient.exitConversation(); //发送保存为草稿事件到会话列表 EventBus.getDefault().post(new Event.Builder().setType(EventType.draft) diff --git a/chatapp/src/main/java/jiguang/chat/adapter/ChattingListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/ChattingListAdapter.java index d38772b3..719b1c05 100644 --- a/chatapp/src/main/java/jiguang/chat/adapter/ChattingListAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/adapter/ChattingListAdapter.java @@ -889,4 +889,10 @@ public boolean onLongClick(View v) { public abstract void onContentLongClick(int position, View view); } + public void stopMediaPlayer() { + if (mController != null) { + mController.stopMediaPlayer(); + } + } + } \ No newline at end of file From 5ecacf0069d41de36eea2d6284eba0ac42345c00 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 16:54:38 +0800 Subject: [PATCH 19/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E8=BD=AF=E9=94=AE=E7=9B=98=E6=9C=AA=E6=94=B6?= =?UTF-8?q?=E8=B5=B7=E9=97=AE=E9=A2=98=EF=BC=8CIM-5392?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/jiguang/chat/activity/BaseActivity.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chatapp/src/main/java/jiguang/chat/activity/BaseActivity.java b/chatapp/src/main/java/jiguang/chat/activity/BaseActivity.java index aaf0ed2a..dec5fa2d 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/BaseActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/BaseActivity.java @@ -69,6 +69,12 @@ public void initTitle(boolean returnBtn, boolean titleLeftDesc, String titleLeft mReturn_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm.isActive() && getCurrentFocus() != null) { + if (getCurrentFocus().getWindowToken() != null) { + imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); + } + } finish(); } }); From 1551dad227571fafc57893e6fc664b0429ef3013 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Wed, 22 May 2019 18:21:41 +0800 Subject: [PATCH 20/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=AE=A4=E7=AE=A1=E7=90=86=E5=91=98=E4=BA=8B=E4=BB=B6=E4=B8=8D?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E9=97=AE=E9=A2=98=EF=BC=8CIM-5429?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jiguang/chat/activity/ChatActivity.java | 47 +++++++++++++++++++ .../chat/controller/ChatItemController.java | 7 +++ 2 files changed, 54 insertions(+) diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java index b06b08b1..08a565f2 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java @@ -35,6 +35,8 @@ import java.io.File; import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; @@ -43,6 +45,7 @@ import cn.jpush.im.android.api.ChatRoomManager; import cn.jpush.im.android.api.JMessageClient; import cn.jpush.im.android.api.callback.GetGroupInfoCallback; +import cn.jpush.im.android.api.callback.GetUserInfoListCallback; import cn.jpush.im.android.api.callback.RequestCallback; import cn.jpush.im.android.api.content.EventNotificationContent; import cn.jpush.im.android.api.content.FileContent; @@ -53,6 +56,7 @@ import cn.jpush.im.android.api.enums.ConversationType; import cn.jpush.im.android.api.enums.MessageDirect; import cn.jpush.im.android.api.event.ChatRoomMessageEvent; +import cn.jpush.im.android.api.event.ChatRoomNotificationEvent; import cn.jpush.im.android.api.event.CommandNotificationEvent; import cn.jpush.im.android.api.event.MessageEvent; import cn.jpush.im.android.api.event.MessageReceiptStatusChangeEvent; @@ -737,6 +741,49 @@ public void onEventMainThread(ChatRoomMessageEvent event) { mChatAdapter.addMsgListToList(messages); } + public void onEventMainThread(ChatRoomNotificationEvent event) { + try { + Constructor constructor = EventNotificationContent.class.getDeclaredConstructor(); + constructor.setAccessible(true); + List messages = new ArrayList<>(); + switch (event.getType()) { + case add_chatroom_admin: + case del_chatroom_admin: + event.getTargetUserInfoList(new GetUserInfoListCallback() { + @Override + public void gotResult(int i, String s, List list) { + if (i == 0) { + for (UserInfo userInfo : list) { + try { + EventNotificationContent content = (EventNotificationContent) constructor.newInstance(); + Field field = content.getClass().getSuperclass().getDeclaredField("contentType"); + field.setAccessible(true); + field.set(content, ContentType.eventNotification); + String user = userInfo.getUserID() == JMessageClient.getMyInfo().getUserID() + ? "你" : TextUtils.isEmpty(userInfo.getNickname()) ? userInfo.getUserName() : userInfo.getNickname(); + String result = event.getType() == ChatRoomNotificationEvent.Type.add_chatroom_admin ? "被设置成管理员" : "被取消管理员"; + content.setStringExtra("msg", user + result); + if (mConv != null) { + messages.add(mConv.createSendMessage(content)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + if (messages.size() > 0) { + mChatAdapter.addMsgListToList(messages); + } + } + } + }); + break; + default: + } + } catch (Exception e) { + e.printStackTrace(); + } + } + public void onEvent(MessageEvent event) { final Message message = event.getMessage(); diff --git a/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java b/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java index 5d607f2f..7d1c061e 100644 --- a/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java +++ b/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java @@ -1086,6 +1086,13 @@ public void onComplete(int status, String desc, File file) { public void handleGroupChangeMsg(Message msg, ViewHolder holder) { + String extraMsg = msg.getContent().getStringExtra("msg"); + if (extraMsg != null) { // 聊天室通知事件消息 + holder.groupChange.setText(extraMsg); + holder.groupChange.setVisibility(View.VISIBLE); + holder.msgTime.setVisibility(View.GONE); + return; + } String content = ((EventNotificationContent) msg.getContent()).getEventText(); EventNotificationContent.EventNotificationType type = ((EventNotificationContent) msg .getContent()).getEventNotificationType(); From 7862161a90ed0a98be46360911479c23fa4a5310 Mon Sep 17 00:00:00 2001 From: jinfeng Date: Thu, 23 May 2019 14:57:14 +0800 Subject: [PATCH 21/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=94=B6=E5=88=B0?= =?UTF-8?q?=E5=A5=BD=E5=8F=8B=E9=82=80=E8=AF=B7=EF=BC=8C=E5=AF=BC=E8=88=AA?= =?UTF-8?q?=E6=A0=8F=E4=B8=AD=E9=80=9A=E8=AE=AF=E5=BD=95=E4=B8=8D=E4=BC=9A?= =?UTF-8?q?=E6=9C=89=E6=8F=90=E7=A4=BA=EF=BC=8CIM-5427?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/FriendRecommendActivity.java | 77 ------------------- .../jiguang/chat/activity/MainActivity.java | 2 - .../activity/fragment/ContactsFragment.java | 8 ++ .../activity/fragment/FriendFragment.java | 2 +- .../chat/adapter/FriendRecommendAdapter.java | 27 ++++--- .../chat/controller/ContactsController.java | 4 + .../java/jiguang/chat/view/ContactsView.java | 7 +- .../main/java/jiguang/chat/view/MainView.java | 12 ++- chatapp/src/main/res/layout/activity_main.xml | 15 ++++ 9 files changed, 59 insertions(+), 95 deletions(-) delete mode 100644 chatapp/src/main/java/jiguang/chat/activity/FriendRecommendActivity.java diff --git a/chatapp/src/main/java/jiguang/chat/activity/FriendRecommendActivity.java b/chatapp/src/main/java/jiguang/chat/activity/FriendRecommendActivity.java deleted file mode 100644 index 2d256082..00000000 --- a/chatapp/src/main/java/jiguang/chat/activity/FriendRecommendActivity.java +++ /dev/null @@ -1,77 +0,0 @@ -package jiguang.chat.activity; - -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.widget.ListView; - -import java.util.List; - -import jiguang.chat.R; -import jiguang.chat.adapter.FriendRecommendAdapter; -import jiguang.chat.application.JGApplication; -import jiguang.chat.database.FriendRecommendEntry; -import jiguang.chat.database.UserEntry; -import jiguang.chat.entity.FriendInvitation; - -/** - * Created by ${chenyn} on 2017/3/17. - * - * 通讯录界面.验证消息 - */ - -public class FriendRecommendActivity extends BaseActivity { - - private ListView mListView; - private FriendRecommendAdapter mAdapter; - private List mList; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_friend_recommend); - - initView(); - - UserEntry user = JGApplication.getUserEntry(); - if (null != user) { - mList = user.getRecommends(); - mAdapter = new FriendRecommendAdapter(this, mList, mDensity, mWidth); - mListView.setAdapter(mAdapter); - } else { - Log.e("FriendRecommendActivity", "Unexpected error: User table null"); - } - } - - private void initView() { - initTitle(true, true, "新的朋友", "", false, ""); - mListView = (ListView) findViewById(R.id.friend_recommend_list_view); - - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - switch (resultCode) { - case JGApplication.RESULT_BUTTON: - int position = data.getIntExtra("position", -1); - int btnState = data.getIntExtra("btn_state", -1); - FriendRecommendEntry entry = mList.get(position); - if (btnState == 2) { - entry.state = FriendInvitation.ACCEPTED.getValue(); - entry.save(); - }else if (btnState == 1) { - entry.state = FriendInvitation.REFUSED.getValue(); - entry.save(); - } - break; - default: - break; - } - } - - protected void onResume() { - super.onResume(); - mAdapter.notifyDataSetChanged(); - } -} diff --git a/chatapp/src/main/java/jiguang/chat/activity/MainActivity.java b/chatapp/src/main/java/jiguang/chat/activity/MainActivity.java index e2ba74c2..e5b116d9 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/MainActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/MainActivity.java @@ -7,10 +7,8 @@ import android.view.KeyEvent; import android.widget.Toast; -import com.yanzhenjie.alertdialog.AlertDialog; import com.yanzhenjie.permission.AndPermission; import com.yanzhenjie.permission.PermissionListener; -import com.yanzhenjie.permission.RationaleListener; import java.util.ArrayList; import java.util.List; diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/ContactsFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/ContactsFragment.java index 65ff379d..1760dab0 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/fragment/ContactsFragment.java +++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/ContactsFragment.java @@ -6,6 +6,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.TextView; import com.google.gson.Gson; @@ -50,6 +51,7 @@ public class ContactsFragment extends BaseFragment { private View mRootView; private ContactsView mContactsView; + private TextView mAllContactNumber; private ContactsController mContactsController; private Activity mContext; @@ -63,6 +65,7 @@ public void onCreate(Bundle savedInstanceState) { (ViewGroup) getActivity().findViewById(R.id.main_view), false); mContactsView = (ContactsView) mRootView.findViewById(R.id.contacts_view); + mAllContactNumber = getActivity().findViewById(R.id.all_contact_number); mContactsView.initModule(mRatio, mDensity); mContactsController = new ContactsController(mContactsView, this.getActivity()); @@ -217,6 +220,8 @@ public void gotResult(int status, String desc, UserInfo userInfo) { //收到好友请求数字 +1 int showNum = SharePreferenceManager.getCachedNewFriendNum() + 1; mContactsView.showNewFriends(showNum); + mAllContactNumber.setVisibility(View.VISIBLE); + mAllContactNumber.setText(String.valueOf(showNum)); SharePreferenceManager.setCachedNewFriendNum(showNum); } } @@ -308,6 +313,9 @@ public void gotResult(int i, String s, List list) { int showNum = SharePreferenceManager.getCachedNewFriendNum() + 1; mContactsView.showNewFriends(showNum); + mAllContactNumber.setVisibility(View.VISIBLE); + mAllContactNumber.setText(String.valueOf(showNum)); + SharePreferenceManager.setCachedNewFriendNum(showNum); } } diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/FriendFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/FriendFragment.java index 0f6e4156..8251d2ef 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/fragment/FriendFragment.java +++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/FriendFragment.java @@ -40,7 +40,7 @@ private void initData() { UserEntry user = JGApplication.getUserEntry(); if (null != user) { mList = user.getRecommends(); - mAdapter = new FriendRecommendAdapter(mContext, mList, mDensity, mWidth); + mAdapter = new FriendRecommendAdapter(this, mList, mDensity, mWidth); mListView.setAdapter(mAdapter); } else { Log.e("FriendRecommendActivity", "Unexpected error: User table null"); diff --git a/chatapp/src/main/java/jiguang/chat/adapter/FriendRecommendAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/FriendRecommendAdapter.java index 77c7b511..d8ecd766 100644 --- a/chatapp/src/main/java/jiguang/chat/adapter/FriendRecommendAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/adapter/FriendRecommendAdapter.java @@ -1,9 +1,10 @@ package jiguang.chat.adapter; -import android.app.Activity; import android.app.Dialog; +import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.support.v4.app.Fragment; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -47,19 +48,21 @@ public class FriendRecommendAdapter extends BaseAdapter { - private Activity mContext; + private Fragment mFragment; + private Context mContext; private List mList = new ArrayList<>(); private LayoutInflater mInflater; private float mDensity; private int mWidth; - public FriendRecommendAdapter(Activity context, List list, float density, + public FriendRecommendAdapter(Fragment fragment, List list, float density, int width) { - this.mContext = context; - this.mList = list; - this.mInflater = LayoutInflater.from(mContext); - this.mDensity = density; - this.mWidth = width; + mFragment = fragment; + mContext = mFragment.getActivity(); + mList = list; + mInflater = LayoutInflater.from(mContext); + mDensity = density; + mWidth = width; } @Override @@ -202,7 +205,7 @@ public void onClick(View view) { intent.putExtra("position", position); intent.putExtra(JGApplication.TARGET_ID, entry.username); intent.putExtra(JGApplication.TARGET_APP_KEY, entry.appKey); - mContext.startActivityForResult(intent, 0); + mFragment.startActivityForResult(intent, 0); //2.已经添加的 --> 好友详情 } else if (entry.state.equals(FriendInvitation.ACCEPTED.getValue())) { JMessageClient.getUserInfo(item.username, new GetUserInfoCallback() { @@ -218,7 +221,7 @@ public void gotResult(int i, String s, UserInfo userInfo) { } intent1.putExtra(JGApplication.TARGET_ID, entry.username); intent1.putExtra(JGApplication.TARGET_APP_KEY, entry.appKey); - mContext.startActivityForResult(intent1, 0); + mFragment.startActivityForResult(intent1, 0); } } }); @@ -229,7 +232,7 @@ public void gotResult(int i, String s, UserInfo userInfo) { intent.putExtra("reason", item.reason); intent.putExtra(JGApplication.TARGET_ID, entry.username); intent.putExtra(JGApplication.TARGET_APP_KEY, entry.appKey); - mContext.startActivityForResult(intent, 0); + mFragment.startActivityForResult(intent, 0); } } @@ -298,7 +301,7 @@ public void onClick(View view) { } intent.putExtra(JGApplication.TARGET_ID, entry.username); intent.putExtra(JGApplication.TARGET_APP_KEY, entry.appKey); - mContext.startActivityForResult(intent, 0); + mFragment.startActivityForResult(intent, 0); } }); } diff --git a/chatapp/src/main/java/jiguang/chat/controller/ContactsController.java b/chatapp/src/main/java/jiguang/chat/controller/ContactsController.java index 4b6c8f58..434ac03a 100644 --- a/chatapp/src/main/java/jiguang/chat/controller/ContactsController.java +++ b/chatapp/src/main/java/jiguang/chat/controller/ContactsController.java @@ -5,6 +5,7 @@ import android.support.v4.app.FragmentActivity; import android.text.TextUtils; import android.view.View; +import android.widget.TextView; import com.activeandroid.ActiveAndroid; @@ -39,12 +40,14 @@ public class ContactsController implements View.OnClickListener, SideBar.OnTouch private Activity mContext; private List mList = new ArrayList<>(); private StickyListAdapter mAdapter; + private TextView mAllContactNumber; private List forDelete = new ArrayList<>(); public ContactsController(ContactsView mContactsView, FragmentActivity context) { this.mContactsView = mContactsView; this.mContext = context; + mAllContactNumber = mContext.findViewById(R.id.all_contact_number); } @@ -61,6 +64,7 @@ public void onClick(View v) { intent.setClass(mContext, VerificationMessageActivity.class); mContext.startActivity(intent); mContactsView.dismissNewFriends(); + mAllContactNumber.setVisibility(View.GONE); break; case R.id.group_ll://群组 intent.setClass(mContext, GroupActivity.class); diff --git a/chatapp/src/main/java/jiguang/chat/view/ContactsView.java b/chatapp/src/main/java/jiguang/chat/view/ContactsView.java index fedd38ea..1469550a 100644 --- a/chatapp/src/main/java/jiguang/chat/view/ContactsView.java +++ b/chatapp/src/main/java/jiguang/chat/view/ContactsView.java @@ -75,13 +75,16 @@ public void initModule(float ratio, float density) { RelativeLayout loadingHeader = (RelativeLayout) mInflater.inflate(R.layout.jmui_drop_down_list_header, null); mLoadingIv = (ImageView) loadingHeader.findViewById(R.id.jmui_loading_img); mLoadingTv = (LinearLayout) loadingHeader.findViewById(R.id.loading_view); - mNewFriendNum.setVisibility(INVISIBLE); mListView.addHeaderView(loadingHeader); mListView.addHeaderView(header, null, false); mListView.setDrawingListUnderStickyHeader(true); mListView.setAreHeadersSticky(true); mListView.setStickyHeaderTopOffset(0); - + if (SharePreferenceManager.getCachedNewFriendNum() > 0) { + showNewFriends(SharePreferenceManager.getCachedNewFriendNum()); + } else { + mNewFriendNum.setVisibility(INVISIBLE); + } } diff --git a/chatapp/src/main/java/jiguang/chat/view/MainView.java b/chatapp/src/main/java/jiguang/chat/view/MainView.java index 64aded12..97ac9bb1 100644 --- a/chatapp/src/main/java/jiguang/chat/view/MainView.java +++ b/chatapp/src/main/java/jiguang/chat/view/MainView.java @@ -6,8 +6,10 @@ import android.util.AttributeSet; import android.widget.Button; import android.widget.RelativeLayout; +import android.widget.TextView; import jiguang.chat.R; +import jiguang.chat.utils.SharePreferenceManager; /** * Created by ${chenyn} on 2017/2/20. @@ -18,12 +20,12 @@ public class MainView extends RelativeLayout { private Button[] mBtnList; private int[] mBtnListID; private ScrollControlViewPager mViewContainer; + private TextView mAllContactNumber; public MainView(Context context, AttributeSet attrs) { super(context, attrs); } - public void initModule() { mBtnListID = new int[] { R.id.actionbar_msg_btn, R.id.actionbar_chatroom_btn, @@ -33,8 +35,16 @@ public void initModule() { mBtnList[i] = (Button) findViewById(mBtnListID[i]); } mViewContainer = (ScrollControlViewPager) findViewById(R.id.viewpager); + mViewContainer.setOffscreenPageLimit(2); mBtnList[0].setTextColor(getResources().getColor(R.color.actionbar_pres_color)); mBtnList[0].setSelected(true); + mAllContactNumber = findViewById(R.id.all_contact_number); + if (SharePreferenceManager.getCachedNewFriendNum() > 0) { + mAllContactNumber.setVisibility(VISIBLE); + mAllContactNumber.setText(String.valueOf(SharePreferenceManager.getCachedNewFriendNum())); + } else { + mAllContactNumber.setVisibility(GONE); + } } public void setOnClickListener(OnClickListener onclickListener) { diff --git a/chatapp/src/main/res/layout/activity_main.xml b/chatapp/src/main/res/layout/activity_main.xml index 26baea99..4ef40f43 100644 --- a/chatapp/src/main/res/layout/activity_main.xml +++ b/chatapp/src/main/res/layout/activity_main.xml @@ -67,6 +67,21 @@ android:drawableTop="@drawable/actionbar_contact_drawable_bg" android:text="@string/actionbar_contact"/> + + Date: Thu, 23 May 2019 15:36:13 +0800 Subject: [PATCH 22/23] =?UTF-8?q?=E6=9B=B4=E6=96=B0StickyListHeadersListVi?= =?UTF-8?q?ew=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=B4=A9=E6=BA=83=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chatapp/build.gradle | 3 +- .../chat/activity/ChooseAtMemberActivity.java | 2 +- .../chat/activity/CreateGroupActivity.java | 2 +- .../chat/activity/FriendListActivity.java | 2 +- .../activity/GroupMemberListActivity.java | 2 +- .../historyfile/adapter/AudioFileAdapter.java | 2 +- .../adapter/DocumentFileAdapter.java | 2 +- .../historyfile/adapter/OtherFileAdapter.java | 2 +- .../historyfile/adapter/VideoFileAdapter.java | 2 +- .../fragment/AudioFileFragment.java | 2 +- .../fragment/DocumentFileFragment.java | 2 +- .../fragment/OtherFileFragment.java | 2 +- .../fragment/VideoFileFragment.java | 2 +- .../jiguang/chat/adapter/AtMemberAdapter.java | 1 + .../chat/adapter/FriendListAdapter.java | 1 + .../chat/adapter/GroupMemberListAdapter.java | 1 + .../chat/adapter/StickyListAdapter.java | 1 + .../adapter/StickyListHeadersAdapter.java | 38 - .../java/jiguang/chat/view/ContactsView.java | 2 +- .../jiguang/chat/view/SelectFriendView.java | 2 +- .../chat/view/listview/AdapterWrapper.java | 3 +- .../SectionIndexerAdapterWrapper.java | 2 +- .../listview/StickyListHeadersListView.java | 1129 ----------------- .../res/layout/activity_choose_at_member.xml | 2 +- .../main/res/layout/activity_create_group.xml | 4 +- .../main/res/layout/activity_friend_list.xml | 2 +- .../res/layout/activity_group_member_list.xml | 2 +- chatapp/src/main/res/layout/document_file.xml | 2 +- .../src/main/res/layout/fragment_contacts.xml | 2 +- 29 files changed, 30 insertions(+), 1191 deletions(-) delete mode 100644 chatapp/src/main/java/jiguang/chat/adapter/StickyListHeadersAdapter.java delete mode 100644 chatapp/src/main/java/jiguang/chat/view/listview/StickyListHeadersListView.java diff --git a/chatapp/build.gradle b/chatapp/build.gradle index bf8ed97d..78d14de1 100644 --- a/chatapp/build.gradle +++ b/chatapp/build.gradle @@ -72,5 +72,6 @@ dependencies { implementation 'cn.jiguang.sdk:jmessage:2.9.0' // 此处以J implementation 'cn.jiguang.sdk:jcore:2.0.0' implementation 'org.greenrobot:eventbus:3.1.1' - implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-25' + implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-26' + implementation 'com.github.mtotschnig:StickyListHeaders:2.7.1' } diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChooseAtMemberActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChooseAtMemberActivity.java index 87d00104..2088bc6f 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/ChooseAtMemberActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/ChooseAtMemberActivity.java @@ -23,7 +23,7 @@ import jiguang.chat.utils.keyboard.widget.EmoticonsEditText; import jiguang.chat.utils.pinyin.UserComparator; import jiguang.chat.utils.sidebar.SideBar; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** diff --git a/chatapp/src/main/java/jiguang/chat/activity/CreateGroupActivity.java b/chatapp/src/main/java/jiguang/chat/activity/CreateGroupActivity.java index 9b6ffcf0..ede79a78 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/CreateGroupActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/CreateGroupActivity.java @@ -30,7 +30,7 @@ import jiguang.chat.utils.keyboard.utils.EmoticonsKeyboardUtils; import jiguang.chat.utils.pinyin.PinyinComparator; import jiguang.chat.utils.sidebar.SideBar; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** diff --git a/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java b/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java index d3b5aa7d..459ca31b 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java @@ -32,7 +32,7 @@ import jiguang.chat.utils.SharePreferenceManager; import jiguang.chat.utils.pinyin.PinyinComparator; import jiguang.chat.utils.sidebar.SideBar; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** * Created by ${chenyn} on 2017/9/21. diff --git a/chatapp/src/main/java/jiguang/chat/activity/GroupMemberListActivity.java b/chatapp/src/main/java/jiguang/chat/activity/GroupMemberListActivity.java index 78919653..a494fbef 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/GroupMemberListActivity.java +++ b/chatapp/src/main/java/jiguang/chat/activity/GroupMemberListActivity.java @@ -21,7 +21,7 @@ import jiguang.chat.application.JGApplication; import jiguang.chat.utils.GroupMemberListComparator; import jiguang.chat.utils.sidebar.SideBar; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** * Created by ${chenyn} on 2017/11/3. diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/AudioFileAdapter.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/AudioFileAdapter.java index 0903b09c..68b94a76 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/AudioFileAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/AudioFileAdapter.java @@ -21,13 +21,13 @@ import cn.jpush.im.android.api.content.FileContent; import jiguang.chat.R; import jiguang.chat.activity.DownLoadActivity; -import jiguang.chat.adapter.StickyListHeadersAdapter; import jiguang.chat.entity.FileItem; import jiguang.chat.entity.SelectedHistoryFileListener; import jiguang.chat.utils.FileHelper; import jiguang.chat.utils.SharePreferenceManager; import jiguang.chat.utils.ViewHolder; import jiguang.chat.view.MyImageView; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** * Created by ${chenyn} on 2017/8/29. diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/DocumentFileAdapter.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/DocumentFileAdapter.java index 3fd881c2..f0e33053 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/DocumentFileAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/DocumentFileAdapter.java @@ -21,12 +21,12 @@ import cn.jpush.im.android.api.content.FileContent; import jiguang.chat.R; import jiguang.chat.activity.DownLoadActivity; -import jiguang.chat.adapter.StickyListHeadersAdapter; import jiguang.chat.entity.FileItem; import jiguang.chat.entity.SelectedHistoryFileListener; import jiguang.chat.utils.FileHelper; import jiguang.chat.utils.SharePreferenceManager; import jiguang.chat.utils.ViewHolder; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** * Created by ${chenyn} on 2017/8/29. diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/OtherFileAdapter.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/OtherFileAdapter.java index 73847c6d..341a714d 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/OtherFileAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/OtherFileAdapter.java @@ -21,13 +21,13 @@ import cn.jpush.im.android.api.content.FileContent; import jiguang.chat.R; import jiguang.chat.activity.DownLoadActivity; -import jiguang.chat.adapter.StickyListHeadersAdapter; import jiguang.chat.entity.FileItem; import jiguang.chat.entity.SelectedHistoryFileListener; import jiguang.chat.utils.FileHelper; import jiguang.chat.utils.SharePreferenceManager; import jiguang.chat.utils.ViewHolder; import jiguang.chat.view.MyImageView; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** * Created by ${chenyn} on 2017/8/29. diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/VideoFileAdapter.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/VideoFileAdapter.java index 5effb3ea..521deecf 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/VideoFileAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/VideoFileAdapter.java @@ -21,13 +21,13 @@ import cn.jpush.im.android.api.content.FileContent; import jiguang.chat.R; import jiguang.chat.activity.DownLoadActivity; -import jiguang.chat.adapter.StickyListHeadersAdapter; import jiguang.chat.entity.FileItem; import jiguang.chat.entity.SelectedHistoryFileListener; import jiguang.chat.utils.FileHelper; import jiguang.chat.utils.SharePreferenceManager; import jiguang.chat.utils.ViewHolder; import jiguang.chat.view.MyImageView; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** * Created by ${chenyn} on 2017/8/29. diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/AudioFileFragment.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/AudioFileFragment.java index 62934329..b74de258 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/AudioFileFragment.java +++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/AudioFileFragment.java @@ -26,7 +26,7 @@ import jiguang.chat.activity.historyfile.adapter.AudioFileAdapter; import jiguang.chat.activity.historyfile.controller.HistoryFileController; import jiguang.chat.entity.FileItem; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** * Created by ${chenyn} on 2017/8/23. diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/DocumentFileFragment.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/DocumentFileFragment.java index 399c474a..c8ee6dc3 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/DocumentFileFragment.java +++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/DocumentFileFragment.java @@ -26,7 +26,7 @@ import jiguang.chat.activity.historyfile.adapter.DocumentFileAdapter; import jiguang.chat.activity.historyfile.controller.HistoryFileController; import jiguang.chat.entity.FileItem; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** * Created by ${chenyn} on 2017/8/23. diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/OtherFileFragment.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/OtherFileFragment.java index db5308de..461d71ad 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/OtherFileFragment.java +++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/OtherFileFragment.java @@ -26,7 +26,7 @@ import jiguang.chat.activity.historyfile.adapter.OtherFileAdapter; import jiguang.chat.activity.historyfile.controller.HistoryFileController; import jiguang.chat.entity.FileItem; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** * Created by ${chenyn} on 2017/8/23. diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/VideoFileFragment.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/VideoFileFragment.java index b76d91f9..55506b0d 100644 --- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/VideoFileFragment.java +++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/VideoFileFragment.java @@ -26,7 +26,7 @@ import jiguang.chat.activity.historyfile.adapter.VideoFileAdapter; import jiguang.chat.activity.historyfile.controller.HistoryFileController; import jiguang.chat.entity.FileItem; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** * Created by ${chenyn} on 2017/8/23. diff --git a/chatapp/src/main/java/jiguang/chat/adapter/AtMemberAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/AtMemberAdapter.java index 55c5180e..4a3b064c 100644 --- a/chatapp/src/main/java/jiguang/chat/adapter/AtMemberAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/adapter/AtMemberAdapter.java @@ -19,6 +19,7 @@ import jiguang.chat.R; import jiguang.chat.utils.ViewHolder; import jiguang.chat.utils.pinyin.HanziToPinyin; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; public class AtMemberAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer { diff --git a/chatapp/src/main/java/jiguang/chat/adapter/FriendListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/FriendListAdapter.java index 4c6a4b05..e90448f1 100644 --- a/chatapp/src/main/java/jiguang/chat/adapter/FriendListAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/adapter/FriendListAdapter.java @@ -20,6 +20,7 @@ import cn.jpush.im.android.api.model.UserInfo; import jiguang.chat.R; import jiguang.chat.database.FriendEntry; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** * Created by ${chenyn} on 2017/9/21. diff --git a/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberListAdapter.java index 4e82b94d..faeeba13 100644 --- a/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberListAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberListAdapter.java @@ -22,6 +22,7 @@ import jiguang.chat.R; import jiguang.chat.activity.GroupMemberListActivity; import jiguang.chat.utils.pinyin.HanziToPinyin; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** * Created by ${chenyn} on 2017/11/3. diff --git a/chatapp/src/main/java/jiguang/chat/adapter/StickyListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/StickyListAdapter.java index 7826604f..4c440cef 100644 --- a/chatapp/src/main/java/jiguang/chat/adapter/StickyListAdapter.java +++ b/chatapp/src/main/java/jiguang/chat/adapter/StickyListAdapter.java @@ -43,6 +43,7 @@ import jiguang.chat.application.JGApplication; import jiguang.chat.database.FriendEntry; import jiguang.chat.utils.photochoose.SelectableRoundedImageView; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** * Created by ${chenyn} on 2017/3/16. diff --git a/chatapp/src/main/java/jiguang/chat/adapter/StickyListHeadersAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/StickyListHeadersAdapter.java deleted file mode 100644 index d818daee..00000000 --- a/chatapp/src/main/java/jiguang/chat/adapter/StickyListHeadersAdapter.java +++ /dev/null @@ -1,38 +0,0 @@ -package jiguang.chat.adapter; - -import android.view.View; -import android.view.ViewGroup; -import android.widget.ListAdapter; - -public interface StickyListHeadersAdapter extends ListAdapter { - /** - * Get a View that displays the header data at the specified position in the - * set. You can either create a View manually or inflate it from an XML layout - * file. - * - * @param position - * The position of the item within the adapter's data set of the item whose - * header view we want. - * @param convertView - * The old view to reuse, if possible. Note: You should check that this view is - * non-null and of an appropriate type before using. If it is not possible to - * convert this view to display the correct data, this method can create a new - * view. - * @param parent - * The parent that this view will eventually be attached to. - * @return - * A View corresponding to the data at the specified position. - */ - View getHeaderView(int position, View convertView, ViewGroup parent); - - /** - * Get the header id associated with the specified position in the list. - * - * @param position - * The position of the item within the adapter's data set whose header id we - * want. - * @return - * The id of the header at the specified position. - */ - long getHeaderId(int position); -} diff --git a/chatapp/src/main/java/jiguang/chat/view/ContactsView.java b/chatapp/src/main/java/jiguang/chat/view/ContactsView.java index 1469550a..1679a7fe 100644 --- a/chatapp/src/main/java/jiguang/chat/view/ContactsView.java +++ b/chatapp/src/main/java/jiguang/chat/view/ContactsView.java @@ -18,7 +18,7 @@ import jiguang.chat.controller.ContactsController; import jiguang.chat.utils.SharePreferenceManager; import jiguang.chat.utils.sidebar.SideBar; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** diff --git a/chatapp/src/main/java/jiguang/chat/view/SelectFriendView.java b/chatapp/src/main/java/jiguang/chat/view/SelectFriendView.java index c0f56cb2..21331812 100644 --- a/chatapp/src/main/java/jiguang/chat/view/SelectFriendView.java +++ b/chatapp/src/main/java/jiguang/chat/view/SelectFriendView.java @@ -11,7 +11,7 @@ import jiguang.chat.R; import jiguang.chat.adapter.StickyListAdapter; import jiguang.chat.utils.sidebar.SideBar; -import jiguang.chat.view.listview.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.StickyListHeadersListView; public class SelectFriendView extends LinearLayout { diff --git a/chatapp/src/main/java/jiguang/chat/view/listview/AdapterWrapper.java b/chatapp/src/main/java/jiguang/chat/view/listview/AdapterWrapper.java index 84f60466..092bf047 100644 --- a/chatapp/src/main/java/jiguang/chat/view/listview/AdapterWrapper.java +++ b/chatapp/src/main/java/jiguang/chat/view/listview/AdapterWrapper.java @@ -12,8 +12,9 @@ import java.util.LinkedList; import java.util.List; + import jiguang.chat.view.CheckableWrapperView; -import jiguang.chat.adapter.StickyListHeadersAdapter; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** diff --git a/chatapp/src/main/java/jiguang/chat/view/listview/SectionIndexerAdapterWrapper.java b/chatapp/src/main/java/jiguang/chat/view/listview/SectionIndexerAdapterWrapper.java index b50c13f9..ab9d2324 100644 --- a/chatapp/src/main/java/jiguang/chat/view/listview/SectionIndexerAdapterWrapper.java +++ b/chatapp/src/main/java/jiguang/chat/view/listview/SectionIndexerAdapterWrapper.java @@ -3,7 +3,7 @@ import android.content.Context; import android.widget.SectionIndexer; -import jiguang.chat.adapter.StickyListHeadersAdapter; +import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; class SectionIndexerAdapterWrapper extends diff --git a/chatapp/src/main/java/jiguang/chat/view/listview/StickyListHeadersListView.java b/chatapp/src/main/java/jiguang/chat/view/listview/StickyListHeadersListView.java deleted file mode 100644 index 2893d272..00000000 --- a/chatapp/src/main/java/jiguang/chat/view/listview/StickyListHeadersListView.java +++ /dev/null @@ -1,1129 +0,0 @@ -package jiguang.chat.view.listview; - -import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.content.Context; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.util.Log; -import android.util.SparseBooleanArray; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.widget.AbsListView; -import android.widget.AbsListView.MultiChoiceModeListener; -import android.widget.AbsListView.OnScrollListener; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.FrameLayout; -import android.widget.ListView; -import android.widget.SectionIndexer; - -import jiguang.chat.R; -import jiguang.chat.adapter.StickyListHeadersAdapter; - - -/** - * Even though this is a FrameLayout subclass we still consider it a ListView. - * This is because of 2 reasons: - * 1. It acts like as ListView. - * 2. It used to be a ListView subclass and refactoring the name would cause compatibility errors. - * - */ -public class StickyListHeadersListView extends FrameLayout { - - public interface OnHeaderClickListener { - void onHeaderClick(StickyListHeadersListView l, View header, - int itemPosition, long headerId, boolean currentlySticky); - } - - /** - * Notifies the listener when the sticky headers top offset has changed. - */ - public interface OnStickyHeaderOffsetChangedListener { - /** - * @param l The view parent - * @param header The currently sticky header being offset. - * This header is not guaranteed to have it's measurements set. - * It is however guaranteed that this view has been measured, - * therefor you should user getMeasured* methods instead of - * get* methods for determining the view's size. - * @param offset The amount the sticky header is offset by towards to top of the screen. - */ - void onStickyHeaderOffsetChanged(StickyListHeadersListView l, View header, int offset); - } - - /** - * Notifies the listener when the sticky header has been updated - */ - public interface OnStickyHeaderChangedListener { - /** - * @param l The view parent - * @param header The new sticky header view. - * @param itemPosition The position of the item within the adapter's data set of - * the item whose header is now sticky. - * @param headerId The id of the new sticky header. - */ - void onStickyHeaderChanged(StickyListHeadersListView l, View header, - int itemPosition, long headerId); - - } - - /* --- Children --- */ - private WrapperViewList mList; - private View mHeader; - - /* --- Header state --- */ - private Long mHeaderId; - // used to not have to call getHeaderId() all the time - private Integer mHeaderPosition; - private Integer mHeaderOffset; - - /* --- Delegates --- */ - private OnScrollListener mOnScrollListenerDelegate; - private AdapterWrapper mAdapter; - - /* --- Settings --- */ - private boolean mAreHeadersSticky = true; - private boolean mClippingToPadding = true; - private boolean mIsDrawingListUnderStickyHeader = true; - private int mStickyHeaderTopOffset = 0; - private int mPaddingLeft = 0; - private int mPaddingTop = 0; - private int mPaddingRight = 0; - private int mPaddingBottom = 0; - - /* --- Touch handling --- */ - private float mDownY; - private boolean mHeaderOwnsTouch; - private float mTouchSlop; - - /* --- Other --- */ - private OnHeaderClickListener mOnHeaderClickListener; - private OnStickyHeaderOffsetChangedListener mOnStickyHeaderOffsetChangedListener; - private OnStickyHeaderChangedListener mOnStickyHeaderChangedListener; - private AdapterWrapperDataSetObserver mDataSetObserver; - private Drawable mDivider; - private int mDividerHeight; - - public StickyListHeadersListView(Context context) { - this(context, null); - } - - public StickyListHeadersListView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.stickyListHeadersListViewStyle); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public StickyListHeadersListView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); - - // Initialize the wrapped list - mList = new WrapperViewList(context); - - // null out divider, dividers are handled by adapter so they look good with headers - mDivider = mList.getDivider(); - mDividerHeight = mList.getDividerHeight(); - mList.setDivider(null); - mList.setDividerHeight(0); - - if (attrs != null) { - TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.StickyListHeadersListView, defStyle, 0); - - try { - // -- View attributes -- - int padding = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_padding, 0); - mPaddingLeft = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingLeft, padding); - mPaddingTop = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingTop, padding); - mPaddingRight = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingRight, padding); - mPaddingBottom = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingBottom, padding); - - setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); - - // Set clip to padding on the list and reset value to default on - // wrapper - mClippingToPadding = a.getBoolean(R.styleable.StickyListHeadersListView_android_clipToPadding, true); - super.setClipToPadding(true); - mList.setClipToPadding(mClippingToPadding); - - // scrollbars - final int scrollBars = a.getInt(R.styleable.StickyListHeadersListView_android_scrollbars, 0x00000200); - mList.setVerticalScrollBarEnabled((scrollBars & 0x00000200) != 0); - mList.setHorizontalScrollBarEnabled((scrollBars & 0x00000100) != 0); - - // overscroll - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { - mList.setOverScrollMode(a.getInt(R.styleable.StickyListHeadersListView_android_overScrollMode, 0)); - } - - // -- ListView attributes -- - mList.setFadingEdgeLength(a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_fadingEdgeLength, - mList.getVerticalFadingEdgeLength())); - final int fadingEdge = a.getInt(R.styleable.StickyListHeadersListView_android_requiresFadingEdge, 0); - if (fadingEdge == 0x00001000) { - mList.setVerticalFadingEdgeEnabled(false); - mList.setHorizontalFadingEdgeEnabled(true); - } else if (fadingEdge == 0x00002000) { - mList.setVerticalFadingEdgeEnabled(true); - mList.setHorizontalFadingEdgeEnabled(false); - } else { - mList.setVerticalFadingEdgeEnabled(false); - mList.setHorizontalFadingEdgeEnabled(false); - } - mList.setCacheColorHint(a - .getColor(R.styleable.StickyListHeadersListView_android_cacheColorHint, mList.getCacheColorHint())); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - mList.setChoiceMode(a.getInt(R.styleable.StickyListHeadersListView_android_choiceMode, - mList.getChoiceMode())); - } - mList.setDrawSelectorOnTop(a.getBoolean(R.styleable.StickyListHeadersListView_android_drawSelectorOnTop, false)); - mList.setFastScrollEnabled(a.getBoolean(R.styleable.StickyListHeadersListView_android_fastScrollEnabled, - mList.isFastScrollEnabled())); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - mList.setFastScrollAlwaysVisible(a.getBoolean( - R.styleable.StickyListHeadersListView_android_fastScrollAlwaysVisible, - mList.isFastScrollAlwaysVisible())); - } - -// mList.setScrollBarStyle(a.getInt(R.styleable.StickyListHeadersListView_android_scrollbarStyle, 0)); - - if (a.hasValue(R.styleable.StickyListHeadersListView_android_listSelector)) { - mList.setSelector(a.getDrawable(R.styleable.StickyListHeadersListView_android_listSelector)); - } - - mList.setScrollingCacheEnabled(a.getBoolean(R.styleable.StickyListHeadersListView_android_scrollingCache, - mList.isScrollingCacheEnabled())); - - if (a.hasValue(R.styleable.StickyListHeadersListView_android_divider)) { - mDivider = a.getDrawable(R.styleable.StickyListHeadersListView_android_divider); - } - - mList.setStackFromBottom(a.getBoolean(R.styleable.StickyListHeadersListView_android_stackFromBottom, false)); - - mDividerHeight = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_dividerHeight, - mDividerHeight); - - mList.setTranscriptMode(a.getInt(R.styleable.StickyListHeadersListView_android_transcriptMode, - ListView.TRANSCRIPT_MODE_DISABLED)); - - // -- StickyListHeaders attributes -- - mAreHeadersSticky = a.getBoolean(R.styleable.StickyListHeadersListView_hasStickyHeaders, true); - mIsDrawingListUnderStickyHeader = a.getBoolean( - R.styleable.StickyListHeadersListView_isDrawingListUnderStickyHeader, - true); - } finally { - a.recycle(); - } - } - - // attach some listeners to the wrapped list - mList.setLifeCycleListener(new WrapperViewListLifeCycleListener()); - mList.setOnScrollListener(new WrapperListScrollListener()); - - addView(mList); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - measureHeader(mHeader); - } - - private void ensureHeaderHasCorrectLayoutParams(View header) { - ViewGroup.LayoutParams lp = header.getLayoutParams(); - if (lp == null) { - lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - header.setLayoutParams(lp); - } else if (lp.height == LayoutParams.MATCH_PARENT || lp.width == LayoutParams.WRAP_CONTENT) { - lp.height = LayoutParams.WRAP_CONTENT; - lp.width = LayoutParams.MATCH_PARENT; - header.setLayoutParams(lp); - } - } - - private void measureHeader(View header) { - if (header != null) { - final int width = getMeasuredWidth() - mPaddingLeft - mPaddingRight; - final int parentWidthMeasureSpec = MeasureSpec.makeMeasureSpec( - width, MeasureSpec.EXACTLY); - final int parentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, - MeasureSpec.UNSPECIFIED); - measureChild(header, parentWidthMeasureSpec, - parentHeightMeasureSpec); - } - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - mList.layout(0, 0, mList.getMeasuredWidth(), getHeight()); - if (mHeader != null) { - MarginLayoutParams lp = (MarginLayoutParams) mHeader.getLayoutParams(); - int headerTop = lp.topMargin; - mHeader.layout(mPaddingLeft, headerTop, mHeader.getMeasuredWidth() - + mPaddingLeft, headerTop + mHeader.getMeasuredHeight()); - } - } - - @Override - protected void dispatchDraw(Canvas canvas) { - // Only draw the list here. - // The header should be drawn right after the lists children are drawn. - // This is done so that the header is above the list items - // but below the list decorators (scroll bars etc). - if (mList.getVisibility() == VISIBLE || mList.getAnimation() != null) { - drawChild(canvas, mList, 0); - } - } - - // Reset values tied the header. also remove header form layout - // This is called in response to the data set or the adapter changing - private void clearHeader() { - if (mHeader != null) { - removeView(mHeader); - mHeader = null; - mHeaderId = null; - mHeaderPosition = null; - mHeaderOffset = null; - - // reset the top clipping length - mList.setTopClippingLength(0); - updateHeaderVisibilities(); - } - } - - private void updateOrClearHeader(int firstVisiblePosition) { - final int adapterCount = mAdapter == null ? 0 : mAdapter.getCount(); - if (adapterCount == 0 || !mAreHeadersSticky) { - return; - } - - final int headerViewCount = mList.getHeaderViewsCount(); - int headerPosition = firstVisiblePosition - headerViewCount; - if (mList.getChildCount() > 0) { - View firstItem = mList.getChildAt(0); - if (firstItem.getBottom() < stickyHeaderTop()) { - headerPosition++; - } - } - - // It is not a mistake to call getFirstVisiblePosition() here. - // Most of the time getFixedFirstVisibleItem() should be called - // but that does not work great together with getChildAt() - final boolean doesListHaveChildren = mList.getChildCount() != 0; - final boolean isFirstViewBelowTop = doesListHaveChildren - && mList.getFirstVisiblePosition() == 0 - && mList.getChildAt(0).getTop() >= stickyHeaderTop(); - final boolean isHeaderPositionOutsideAdapterRange = headerPosition > adapterCount - 1 - || headerPosition < 0; - if (!doesListHaveChildren || isHeaderPositionOutsideAdapterRange || isFirstViewBelowTop) { - clearHeader(); - return; - } - - updateHeader(headerPosition); - } - - private void updateHeader(int headerPosition) { - - // check if there is a new header should be sticky - if (mHeaderPosition == null || mHeaderPosition != headerPosition) { - mHeaderPosition = headerPosition; - final long headerId = mAdapter.getHeaderId(headerPosition); - if (mHeaderId == null || mHeaderId != headerId) { - mHeaderId = headerId; - final View header = mAdapter.getHeaderView(mHeaderPosition, mHeader, this); - if (mHeader != header) { - if (header == null) { - throw new NullPointerException("header may not be null"); - } - swapHeader(header); - } - ensureHeaderHasCorrectLayoutParams(mHeader); - measureHeader(mHeader); - if (mOnStickyHeaderChangedListener != null) { - mOnStickyHeaderChangedListener.onStickyHeaderChanged(this, mHeader, headerPosition, mHeaderId); - } - // Reset mHeaderOffset to null ensuring - // that it will be set on the header and - // not skipped for performance reasons. - mHeaderOffset = null; - } - } - - int headerOffset = stickyHeaderTop(); - - // Calculate new header offset - // Skip looking at the first view. it never matters because it always - // results in a headerOffset = 0 - for (int i = 0; i < mList.getChildCount(); i++) { - final View child = mList.getChildAt(i); - final boolean doesChildHaveHeader = child instanceof WrapperView && ((WrapperView) child).hasHeader(); - final boolean isChildFooter = mList.containsFooterView(child); - if (child.getTop() >= stickyHeaderTop() && (doesChildHaveHeader || isChildFooter)) { - headerOffset = Math.min(child.getTop() - mHeader.getMeasuredHeight(), headerOffset); - break; - } - } - - setHeaderOffet(headerOffset); - - if (!mIsDrawingListUnderStickyHeader) { - mList.setTopClippingLength(mHeader.getMeasuredHeight() - + mHeaderOffset); - } - - updateHeaderVisibilities(); - } - - private void swapHeader(View newHeader) { - if (mHeader != null) { - removeView(mHeader); - } - mHeader = newHeader; - addView(mHeader); - if (mOnHeaderClickListener != null) { - mHeader.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mOnHeaderClickListener.onHeaderClick( - StickyListHeadersListView.this, mHeader, - mHeaderPosition, mHeaderId, true); - } - }); - } - mHeader.setClickable(true); - } - - // hides the headers in the list under the sticky header. - // Makes sure the jmui_other ones are showing - private void updateHeaderVisibilities() { - int top = stickyHeaderTop(); - int childCount = mList.getChildCount(); - for (int i = 0; i < childCount; i++) { - - // ensure child is a wrapper view - View child = mList.getChildAt(i); - if (!(child instanceof WrapperView)) { - continue; - } - - // ensure wrapper view child has a header - WrapperView wrapperViewChild = (WrapperView) child; - if (!wrapperViewChild.hasHeader()) { - continue; - } - - // update header views visibility - View childHeader = wrapperViewChild.mHeader; - if (wrapperViewChild.getTop() < top) { - if (childHeader.getVisibility() != View.INVISIBLE) { - childHeader.setVisibility(View.INVISIBLE); - } - } else { - if (childHeader.getVisibility() != View.VISIBLE) { - childHeader.setVisibility(View.VISIBLE); - } - } - } - } - - // Wrapper around setting the header offset in different ways depending on - // the API version - @SuppressLint("NewApi") - private void setHeaderOffet(int offset) { - if (mHeaderOffset == null || mHeaderOffset != offset) { - mHeaderOffset = offset; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - mHeader.setTranslationY(mHeaderOffset); - } else { - MarginLayoutParams params = (MarginLayoutParams) mHeader.getLayoutParams(); - params.topMargin = mHeaderOffset; - mHeader.setLayoutParams(params); - } - if (mOnStickyHeaderOffsetChangedListener != null) { - mOnStickyHeaderOffsetChangedListener.onStickyHeaderOffsetChanged(this, mHeader, -mHeaderOffset); - } - } - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - int action = ev.getAction() & MotionEvent.ACTION_MASK; - if (action == MotionEvent.ACTION_DOWN) { - mDownY = ev.getY(); - mHeaderOwnsTouch = mHeader != null && mDownY <= mHeader.getHeight() + mHeaderOffset; - } - - boolean handled; - if (mHeaderOwnsTouch) { - if (mHeader != null && Math.abs(mDownY - ev.getY()) <= mTouchSlop) { - handled = mHeader.dispatchTouchEvent(ev); - } else { - if (mHeader != null) { - MotionEvent cancelEvent = MotionEvent.obtain(ev); - cancelEvent.setAction(MotionEvent.ACTION_CANCEL); - mHeader.dispatchTouchEvent(cancelEvent); - cancelEvent.recycle(); - } - - MotionEvent downEvent = MotionEvent.obtain(ev.getDownTime(), ev.getEventTime(), ev.getAction(), ev.getX(), mDownY, ev.getMetaState()); - downEvent.setAction(MotionEvent.ACTION_DOWN); - handled = mList.dispatchTouchEvent(downEvent); - downEvent.recycle(); - mHeaderOwnsTouch = false; - } - } else { - handled = mList.dispatchTouchEvent(ev); - } - - return handled; - } - - private class AdapterWrapperDataSetObserver extends DataSetObserver { - - @Override - public void onChanged() { - clearHeader(); - } - - @Override - public void onInvalidated() { - clearHeader(); - } - - } - - private class WrapperListScrollListener implements OnScrollListener { - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, - int visibleItemCount, int totalItemCount) { - if (mOnScrollListenerDelegate != null) { - mOnScrollListenerDelegate.onScroll(view, firstVisibleItem, - visibleItemCount, totalItemCount); - } - updateOrClearHeader(mList.getFixedFirstVisibleItem()); - } - - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - if (mOnScrollListenerDelegate != null) { - mOnScrollListenerDelegate.onScrollStateChanged(view, - scrollState); - } - } - - } - - private class WrapperViewListLifeCycleListener implements WrapperViewList.LifeCycleListener { - - @Override - public void onDispatchDrawOccurred(Canvas canvas) { - // onScroll is not called often at all before froyo - // therefor we need to update the header here as well. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { - updateOrClearHeader(mList.getFixedFirstVisibleItem()); - } - if (mHeader != null) { - if (mClippingToPadding) { - canvas.save(); - canvas.clipRect(0, mPaddingTop, getRight(), getBottom()); - drawChild(canvas, mHeader, 0); - canvas.restore(); - } else { - drawChild(canvas, mHeader, 0); - } - } - } - - } - - private class AdapterWrapperHeaderClickHandler implements - AdapterWrapper.OnHeaderClickListener { - - @Override - public void onHeaderClick(View header, int itemPosition, long headerId) { - mOnHeaderClickListener.onHeaderClick( - StickyListHeadersListView.this, header, itemPosition, - headerId, false); - } - - } - - private boolean isStartOfSection(int position) { - return position == 0 || mAdapter.getHeaderId(position) != mAdapter.getHeaderId(position - 1); - } - - public int getHeaderOverlap(int position) { - boolean isStartOfSection = isStartOfSection(Math.max(0, position - getHeaderViewsCount())); - if (!isStartOfSection) { - View header = mAdapter.getHeaderView(position, null, mList); - if (header == null) { - throw new NullPointerException("header may not be null"); - } - ensureHeaderHasCorrectLayoutParams(header); - measureHeader(header); - return header.getMeasuredHeight(); - } - return 0; - } - - private int stickyHeaderTop() { - return mStickyHeaderTopOffset + (mClippingToPadding ? mPaddingTop : 0); - } - - /* ---------- StickyListHeaders specific API ---------- */ - - public void setAreHeadersSticky(boolean areHeadersSticky) { - mAreHeadersSticky = areHeadersSticky; - if (!areHeadersSticky) { - clearHeader(); - } else { - updateOrClearHeader(mList.getFixedFirstVisibleItem()); - } - // invalidating the list will trigger dispatchDraw() - mList.invalidate(); - } - - public boolean areHeadersSticky() { - return mAreHeadersSticky; - } - - /** - * Use areHeadersSticky() method instead - */ - @Deprecated - public boolean getAreHeadersSticky() { - return areHeadersSticky(); - } - - /** - * @param stickyHeaderTopOffset The offset of the sticky header fom the top of the view - */ - public void setStickyHeaderTopOffset(int stickyHeaderTopOffset) { - mStickyHeaderTopOffset = stickyHeaderTopOffset; - updateOrClearHeader(mList.getFixedFirstVisibleItem()); - } - - public int getStickyHeaderTopOffset() { - return mStickyHeaderTopOffset; - } - - public void setDrawingListUnderStickyHeader( - boolean drawingListUnderStickyHeader) { - mIsDrawingListUnderStickyHeader = drawingListUnderStickyHeader; - // reset the top clipping length - mList.setTopClippingLength(0); - } - - public boolean isDrawingListUnderStickyHeader() { - return mIsDrawingListUnderStickyHeader; - } - - public void setOnHeaderClickListener(OnHeaderClickListener listener) { - mOnHeaderClickListener = listener; - if (mAdapter != null) { - if (mOnHeaderClickListener != null) { - mAdapter.setOnHeaderClickListener(new AdapterWrapperHeaderClickHandler()); - - if (mHeader != null) { - mHeader.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mOnHeaderClickListener.onHeaderClick( - StickyListHeadersListView.this, mHeader, - mHeaderPosition, mHeaderId, true); - } - }); - } - } else { - mAdapter.setOnHeaderClickListener(null); - } - } - } - - public void setOnStickyHeaderOffsetChangedListener(OnStickyHeaderOffsetChangedListener listener) { - mOnStickyHeaderOffsetChangedListener = listener; - } - - public void setOnStickyHeaderChangedListener(OnStickyHeaderChangedListener listener) { - mOnStickyHeaderChangedListener = listener; - } - - public View getListChildAt(int index) { - return mList.getChildAt(index); - } - - public int getListChildCount() { - return mList.getChildCount(); - } - - /** - * Use the method with extreme caution!! Changing any values on the - * underlying ListView might break everything. - * - * @return the ListView backing this view. - */ - public ListView getWrappedList() { - return mList; - } - - private boolean requireSdkVersion(int versionCode) { - if (Build.VERSION.SDK_INT < versionCode) { - Log.e("StickyListHeaders", "Api lvl must be at least " + versionCode + " to call this method"); - return false; - } - return true; - } - - /* ---------- ListView delegate methods ---------- */ - - public void setAdapter(StickyListHeadersAdapter adapter) { - if (adapter == null) { - if (mAdapter instanceof SectionIndexerAdapterWrapper) { - ((SectionIndexerAdapterWrapper) mAdapter).mSectionIndexerDelegate = null; - } - if (mAdapter != null) { - mAdapter.mDelegate = null; - } - mList.setAdapter(null); - clearHeader(); - return; - } - if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(mDataSetObserver); - } - - if (adapter instanceof SectionIndexer) { - mAdapter = new SectionIndexerAdapterWrapper(getContext(), adapter); - } else { - mAdapter = new AdapterWrapper(getContext(), adapter); - } - mDataSetObserver = new AdapterWrapperDataSetObserver(); - mAdapter.registerDataSetObserver(mDataSetObserver); - - if (mOnHeaderClickListener != null) { - mAdapter.setOnHeaderClickListener(new AdapterWrapperHeaderClickHandler()); - } else { - mAdapter.setOnHeaderClickListener(null); - } - - mAdapter.setDivider(mDivider, mDividerHeight); - - mList.setAdapter(mAdapter); - clearHeader(); - } - - public StickyListHeadersAdapter getAdapter() { - return mAdapter == null ? null : mAdapter.mDelegate; - } - - public void setDivider(Drawable divider) { - mDivider = divider; - if (mAdapter != null) { - mAdapter.setDivider(mDivider, mDividerHeight); - } - } - - public void setDividerHeight(int dividerHeight) { - mDividerHeight = dividerHeight; - if (mAdapter != null) { - mAdapter.setDivider(mDivider, mDividerHeight); - } - } - - public Drawable getDivider() { - return mDivider; - } - - public int getDividerHeight() { - return mDividerHeight; - } - - public void setOnScrollListener(OnScrollListener onScrollListener) { - mOnScrollListenerDelegate = onScrollListener; - } - - @Override - public void setOnTouchListener(final OnTouchListener l) { - if (l != null) { - mList.setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return l.onTouch(StickyListHeadersListView.this, event); - } - }); - } else { - mList.setOnTouchListener(null); - } - } - - public void setOnItemClickListener(OnItemClickListener listener) { - mList.setOnItemClickListener(listener); - } - - public void setOnItemLongClickListener(OnItemLongClickListener listener) { - mList.setOnItemLongClickListener(listener); - } - - public void addHeaderView(View v, Object data, boolean isSelectable) { - mList.addHeaderView(v, data, isSelectable); - } - - public void addHeaderView(View v) { - mList.addHeaderView(v); - } - - public void removeHeaderView(View v) { - mList.removeHeaderView(v); - } - - public int getHeaderViewsCount() { - return mList.getHeaderViewsCount(); - } - - public void addFooterView(View v, Object data, boolean isSelectable) { - mList.addFooterView(v, data, isSelectable); - } - - public void addFooterView(View v) { - mList.addFooterView(v); - } - - public void removeFooterView(View v) { - mList.removeFooterView(v); - } - - public int getFooterViewsCount() { - return mList.getFooterViewsCount(); - } - - public void setEmptyView(View v) { - mList.setEmptyView(v); - } - - public View getEmptyView() { - return mList.getEmptyView(); - } - - @Override - public boolean isVerticalScrollBarEnabled() { - return mList.isVerticalScrollBarEnabled(); - } - - @Override - public boolean isHorizontalScrollBarEnabled() { - return mList.isHorizontalScrollBarEnabled(); - } - - @Override - public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) { - mList.setVerticalScrollBarEnabled(verticalScrollBarEnabled); - } - - @Override - public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) { - mList.setHorizontalScrollBarEnabled(horizontalScrollBarEnabled); - } - - @Override - @TargetApi(Build.VERSION_CODES.GINGERBREAD) - public int getOverScrollMode() { - if (requireSdkVersion(Build.VERSION_CODES.GINGERBREAD)) { - return mList.getOverScrollMode(); - } - return 0; - } - - @Override - @TargetApi(Build.VERSION_CODES.GINGERBREAD) - public void setOverScrollMode(int mode) { - if (requireSdkVersion(Build.VERSION_CODES.GINGERBREAD)) { - if (mList != null) { - mList.setOverScrollMode(mode); - } - } - } - - @TargetApi(Build.VERSION_CODES.FROYO) - public void smoothScrollBy(int distance, int duration) { - if (requireSdkVersion(Build.VERSION_CODES.FROYO)) { - mList.smoothScrollBy(distance, duration); - } - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void smoothScrollByOffset(int offset) { - if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) { - mList.smoothScrollByOffset(offset); - } - } - - @SuppressLint("NewApi") - @TargetApi(Build.VERSION_CODES.FROYO) - public void smoothScrollToPosition(int position) { - if (requireSdkVersion(Build.VERSION_CODES.FROYO)) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - mList.smoothScrollToPosition(position); - } else { - int offset = mAdapter == null ? 0 : getHeaderOverlap(position); - offset -= mClippingToPadding ? 0 : mPaddingTop; - mList.smoothScrollToPositionFromTop(position, offset); - } - } - } - - @TargetApi(Build.VERSION_CODES.FROYO) - public void smoothScrollToPosition(int position, int boundPosition) { - if (requireSdkVersion(Build.VERSION_CODES.FROYO)) { - mList.smoothScrollToPosition(position, boundPosition); - } - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void smoothScrollToPositionFromTop(int position, int offset) { - if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) { - offset += mAdapter == null ? 0 : getHeaderOverlap(position); - offset -= mClippingToPadding ? 0 : mPaddingTop; - mList.smoothScrollToPositionFromTop(position, offset); - } - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void smoothScrollToPositionFromTop(int position, int offset, - int duration) { - if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) { - offset += mAdapter == null ? 0 : getHeaderOverlap(position); - offset -= mClippingToPadding ? 0 : mPaddingTop; - mList.smoothScrollToPositionFromTop(position, offset, duration); - } - } - - public void setSelection(int position) { - setSelectionFromTop(position, 0); - } - - public void setSelectionAfterHeaderView() { - mList.setSelectionAfterHeaderView(); - } - - public void setSelectionFromTop(int position, int y) { - y += mAdapter == null ? 0 : getHeaderOverlap(position); - y -= mClippingToPadding ? 0 : mPaddingTop; - mList.setSelectionFromTop(position, y); - } - - public void setSelector(Drawable sel) { - mList.setSelector(sel); - } - - public void setSelector(int resID) { - mList.setSelector(resID); - } - - public int getFirstVisiblePosition() { - return mList.getFirstVisiblePosition(); - } - - public int getLastVisiblePosition() { - return mList.getLastVisiblePosition(); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void setChoiceMode(int choiceMode) { - mList.setChoiceMode(choiceMode); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void setItemChecked(int position, boolean value) { - mList.setItemChecked(position, value); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public int getCheckedItemCount() { - if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) { - return mList.getCheckedItemCount(); - } - return 0; - } - - @TargetApi(11) - public long[] getCheckedItemIds() { - if (requireSdkVersion(Build.VERSION_CODES.FROYO)) { - return mList.getCheckedItemIds(); - } - return null; - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public int getCheckedItemPosition() { - return mList.getCheckedItemPosition(); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public SparseBooleanArray getCheckedItemPositions() { - return mList.getCheckedItemPositions(); - } - - public int getCount() { - return mList.getCount(); - } - - public Object getItemAtPosition(int position) { - return mList.getItemAtPosition(position); - } - - public long getItemIdAtPosition(int position) { - return mList.getItemIdAtPosition(position); - } - - @Override - public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) { - mList.setOnCreateContextMenuListener(l); - } - - @Override - public boolean showContextMenu() { - return mList.showContextMenu(); - } - - public void invalidateViews() { - mList.invalidateViews(); - } - - @Override - public void setClipToPadding(boolean clipToPadding) { - if (mList != null) { - mList.setClipToPadding(clipToPadding); - } - mClippingToPadding = clipToPadding; - } - - @Override - public void setPadding(int left, int top, int right, int bottom) { - mPaddingLeft = left; - mPaddingTop = top; - mPaddingRight = right; - mPaddingBottom = bottom; - - if (mList != null) { - mList.setPadding(left, top, right, bottom); - } - super.setPadding(0, 0, 0, 0); - requestLayout(); - } - - /* - * Overrides an @hide method in View - */ - protected void recomputePadding() { - setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); - } - - @Override - public int getPaddingLeft() { - return mPaddingLeft; - } - - @Override - public int getPaddingTop() { - return mPaddingTop; - } - - @Override - public int getPaddingRight() { - return mPaddingRight; - } - - @Override - public int getPaddingBottom() { - return mPaddingBottom; - } - - public void setFastScrollEnabled(boolean fastScrollEnabled) { - mList.setFastScrollEnabled(fastScrollEnabled); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void setFastScrollAlwaysVisible(boolean alwaysVisible) { - if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) { - mList.setFastScrollAlwaysVisible(alwaysVisible); - } - } - - /** - * @return true if the fast scroller will always show. False on pre-Honeycomb devices. - * @see AbsListView#isFastScrollAlwaysVisible() - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public boolean isFastScrollAlwaysVisible() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - return false; - } - return mList.isFastScrollAlwaysVisible(); - } - - public void setScrollBarStyle(int style) { - mList.setScrollBarStyle(style); - } - - public int getScrollBarStyle() { - return mList.getScrollBarStyle(); - } - - public int getPositionForView(View view) { - return mList.getPositionForView(view); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void setMultiChoiceModeListener(MultiChoiceModeListener listener) { - if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) { - mList.setMultiChoiceModeListener(listener); - } - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - if (superState != BaseSavedState.EMPTY_STATE) { - throw new IllegalStateException("Handling non empty state of parent class is not implemented"); - } - return mList.onSaveInstanceState(); - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - super.onRestoreInstanceState(BaseSavedState.EMPTY_STATE); - mList.onRestoreInstanceState(state); - } - - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - @Override - public boolean canScrollVertically(int direction) { - return mList.canScrollVertically(direction); - } - - public void setTranscriptMode(int mode) { - mList.setTranscriptMode(mode); - } - - public void setBlockLayoutChildren(boolean blockLayoutChildren) { - mList.setBlockLayoutChildren(blockLayoutChildren); - } - - public void setStackFromBottom(boolean stackFromBottom) { - mList.setStackFromBottom(stackFromBottom); - } - - public boolean isStackFromBottom() { - return mList.isStackFromBottom(); - } -} diff --git a/chatapp/src/main/res/layout/activity_choose_at_member.xml b/chatapp/src/main/res/layout/activity_choose_at_member.xml index 4bf1606c..c06b49fb 100644 --- a/chatapp/src/main/res/layout/activity_choose_at_member.xml +++ b/chatapp/src/main/res/layout/activity_choose_at_member.xml @@ -60,7 +60,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - + - - - - Date: Thu, 23 May 2019 15:45:30 +0800 Subject: [PATCH 23/23] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=AC=E5=BC=80?= =?UTF-8?q?=E7=BE=A4=E6=90=9C=E7=B4=A2=E6=A0=8F=E9=BB=98=E8=AE=A4=E6=96=87?= =?UTF-8?q?=E5=AD=97=E4=B8=8D=E6=AD=A3=E7=A1=AE=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?IM-5431?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chatapp/src/main/res/layout/activity_search_add_open_group.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chatapp/src/main/res/layout/activity_search_add_open_group.xml b/chatapp/src/main/res/layout/activity_search_add_open_group.xml index 200228a3..d1217a18 100644 --- a/chatapp/src/main/res/layout/activity_search_add_open_group.xml +++ b/chatapp/src/main/res/layout/activity_search_add_open_group.xml @@ -26,7 +26,7 @@ android:layout_marginLeft="14dp" android:layout_weight="1" android:background="@null" - android:hint="搜索用户名" + android:hint="搜索群组ID" android:inputType="number" android:maxLength="15" android:maxLines="1"