huangxinbao

add whitebroard and emoji icon

正在显示 100 个修改的文件 包含 4213 行增加161 行删除

要显示太多修改。

为保证性能只显示 100 of 100+ 个文件。

@@ -36,8 +36,10 @@ dependencies { @@ -36,8 +36,10 @@ dependencies {
36 testCompile 'junit:junit:4.12' 36 testCompile 'junit:junit:4.12'
37 compile 'com.jakewharton:butterknife:8.5.1' 37 compile 'com.jakewharton:butterknife:8.5.1'
38 annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1' 38 annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
39 - compile project(':xdy')  
40 -  
41 compile 'com.android.support:design:23.4.0' 39 compile 'com.android.support:design:23.4.0'
42 compile 'com.squareup.picasso:picasso:2.3.2' 40 compile 'com.squareup.picasso:picasso:2.3.2'
  41 + compile 'com.github.bumptech.glide:glide:3.7.0'
  42 + compile project(':xdy')
  43 + compile 'com.rockerhieu.emojicon:library:1.3.1'
  44 + compile 'org.kymjs.kjframe:kjframe:2.6'
43 } 45 }
@@ -21,6 +21,7 @@ import android.widget.TextView; @@ -21,6 +21,7 @@ import android.widget.TextView;
21 21
22 import com.eventhandle.SmartEventCallback; 22 import com.eventhandle.SmartEventCallback;
23 import com.google.gson.Gson; 23 import com.google.gson.Gson;
  24 +import com.mang.xdy.common.Constants;
24 import com.mang.xdy.core.XdySdk; 25 import com.mang.xdy.core.XdySdk;
25 import com.mang.xdy.demo.R; 26 import com.mang.xdy.demo.R;
26 import com.mang.xdy.demo.adapter.SimpleFragmentPagerAdapter; 27 import com.mang.xdy.demo.adapter.SimpleFragmentPagerAdapter;
@@ -81,7 +82,7 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -81,7 +82,7 @@ public class AudioPublisherActivity extends AppCompatActivity {
81 break; 82 break;
82 case -1: 83 case -1:
83 //退出 84 //退出
84 - XdySdk.setAsyncApi("leaveClass", ""); 85 + XdySdk.api("leaveClass", "");
85 break; 86 break;
86 case 0: 87 case 0:
87 parseJoinClass((String) msg.obj,true); 88 parseJoinClass((String) msg.obj,true);
@@ -175,7 +176,7 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -175,7 +176,7 @@ public class AudioPublisherActivity extends AppCompatActivity {
175 176
176 public void init() { 177 public void init() {
177 initClass = getIntent().getStringExtra("init"); 178 initClass = getIntent().getStringExtra("init");
178 - XdySdk.setAsyncApi("init", initClass); 179 + XdySdk.api("init", initClass);
179 180
180 } 181 }
181 //判断解析是否有密码 182 //判断解析是否有密码
@@ -210,14 +211,14 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -210,14 +211,14 @@ public class AudioPublisherActivity extends AppCompatActivity {
210 String temp=new Gson().toJson(joinClass); 211 String temp=new Gson().toJson(joinClass);
211 String jsonParmp = XdyStringUtils.stringToJson(temp, true); 212 String jsonParmp = XdyStringUtils.stringToJson(temp, true);
212 XdyLogUtil.e("加入课堂", jsonParmp); 213 XdyLogUtil.e("加入课堂", jsonParmp);
213 - XdySdk.setAsyncApi("joinClass", jsonParmp); 214 + XdySdk.api("joinClass", jsonParmp);
214 } 215 }
215 216
216 public void playVideo(String response) { 217 public void playVideo(String response) {
217 VideoPlayBean videoPlayBean = JsonUtil.parseJsonToBean(response, VideoPlayBean.class); 218 VideoPlayBean videoPlayBean = JsonUtil.parseJsonToBean(response, VideoPlayBean.class);
218 if (videoPlayBean != null && videoPlayBean.getRtmpUrl() != null) 219 if (videoPlayBean != null && videoPlayBean.getRtmpUrl() != null)
219 XdyLogUtil.e(TAG, "执行了ss" + videoPlayBean.getRtmpUrl()); 220 XdyLogUtil.e(TAG, "执行了ss" + videoPlayBean.getRtmpUrl());
220 - XdySdk.setAsyncApi("playVideo", videoPlayBean.getRtmpUrl(), surfaceviewPlayVideo, AudioPublisherActivity.this, new EventHande_Video()); 221 + XdySdk.api("playVideo", videoPlayBean.getRtmpUrl(), surfaceviewPlayVideo, AudioPublisherActivity.this, new EventHande_Video());
221 // img_playVideo_novideo.setVisibility(View.GONE); 222 // img_playVideo_novideo.setVisibility(View.GONE);
222 ToastUtil.showToastshort("视频播放初始化",AudioPublisherActivity.this); 223 ToastUtil.showToastshort("视频播放初始化",AudioPublisherActivity.this);
223 } 224 }
@@ -226,7 +227,7 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -226,7 +227,7 @@ public class AudioPublisherActivity extends AppCompatActivity {
226 AudioPlayBean audioPlayBean = JsonUtil.parseJsonToBean(response, AudioPlayBean.class); 227 AudioPlayBean audioPlayBean = JsonUtil.parseJsonToBean(response, AudioPlayBean.class);
227 if (audioPlayBean != null && audioPlayBean.getRtmpUrl() != null) { 228 if (audioPlayBean != null && audioPlayBean.getRtmpUrl() != null) {
228 XdyLogUtil.e(TAG, "执行了" + audioPlayBean.getRtmpUrl()); 229 XdyLogUtil.e(TAG, "执行了" + audioPlayBean.getRtmpUrl());
229 - XdySdk.setAsyncApi("playAudio", audioPlayBean.getRtmpUrl(), null, AudioPublisherActivity.this, new EventHande_Video()); 230 + XdySdk.api("playAudio", audioPlayBean.getRtmpUrl(), null, AudioPublisherActivity.this, new EventHande_Video());
230 // img_playVideo_novideo.setVisibility(View.GONE); 231 // img_playVideo_novideo.setVisibility(View.GONE);
231 ToastUtil.showToastshort("音频播放初始化",AudioPublisherActivity.this); 232 ToastUtil.showToastshort("音频播放初始化",AudioPublisherActivity.this);
232 } 233 }
@@ -251,7 +252,7 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -251,7 +252,7 @@ public class AudioPublisherActivity extends AppCompatActivity {
251 252
252 String jsonParmp = XdyStringUtils.stringToJson(temp, true); 253 String jsonParmp = XdyStringUtils.stringToJson(temp, true);
253 XdyLogUtil.e(TAG, "文档" + jsonParmp); 254 XdyLogUtil.e(TAG, "文档" + jsonParmp);
254 - XdySdk.setAsyncApi("getDocImageFullPath", jsonParmp); 255 + XdySdk.api("getDocImageFullPath", jsonParmp);
255 } 256 }
256 } 257 }
257 258
@@ -262,7 +263,7 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -262,7 +263,7 @@ public class AudioPublisherActivity extends AppCompatActivity {
262 "}"; 263 "}";
263 String jsonParmp = XdyStringUtils.stringToJson(temp, true); 264 String jsonParmp = XdyStringUtils.stringToJson(temp, true);
264 XdyLogUtil.e(TAG, "聊天" + jsonParmp); 265 XdyLogUtil.e(TAG, "聊天" + jsonParmp);
265 - XdySdk.setAsyncApi("sendChatMsg", jsonParmp); 266 + XdySdk.api("sendChatMsg", jsonParmp);
266 267
267 } 268 }
268 269
@@ -280,7 +281,7 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -280,7 +281,7 @@ public class AudioPublisherActivity extends AppCompatActivity {
280 String ids_new = "getVideoPublishPath"; 281 String ids_new = "getVideoPublishPath";
281 String tem = "{ \"type\": \"live\"}"; 282 String tem = "{ \"type\": \"live\"}";
282 String s = XdyStringUtils.stringToJson(tem, true); 283 String s = XdyStringUtils.stringToJson(tem, true);
283 - XdySdk.setAsyncApi(ids_new, s); 284 + XdySdk.api(ids_new, s);
284 } 285 }
285 286
286 public void publisherVideo(String response) { 287 public void publisherVideo(String response) {
@@ -294,10 +295,10 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -294,10 +295,10 @@ public class AudioPublisherActivity extends AppCompatActivity {
294 // String url_text="rtmp://123.56.205.116:6000/live/h5dev_1999957388_980_983041_1491813919"; 295 // String url_text="rtmp://123.56.205.116:6000/live/h5dev_1999957388_980_983041_1491813919";
295 publisherSuccess=liveBean.getPublishUrl(); 296 publisherSuccess=liveBean.getPublishUrl();
296 if(isPusherAudio){ 297 if(isPusherAudio){
297 - XdySdk.setAsyncApi("publishAudio", liveBean.getPublishUrl(), surfaceview_pubisherVideo, AudioPublisherActivity.this,new EventHande()); 298 + XdySdk.api("publishAudio", liveBean.getPublishUrl(), surfaceview_pubisherVideo, AudioPublisherActivity.this,new EventHande());
298 ToastUtil.showToastshort("推送纯音频初始化中",AudioPublisherActivity.this); 299 ToastUtil.showToastshort("推送纯音频初始化中",AudioPublisherActivity.this);
299 }else{ 300 }else{
300 - XdySdk.setAsyncApi("publishVideo", liveBean.getPublishUrl(), surfaceview_pubisherVideo, AudioPublisherActivity.this,new EventHande()); 301 + XdySdk.api("publishVideo", liveBean.getPublishUrl(), surfaceview_pubisherVideo, AudioPublisherActivity.this,new EventHande());
301 ToastUtil.showToastshort("推送视频初始化中",AudioPublisherActivity.this); 302 ToastUtil.showToastshort("推送视频初始化中",AudioPublisherActivity.this);
302 } 303 }
303 304
@@ -307,7 +308,7 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -307,7 +308,7 @@ public class AudioPublisherActivity extends AppCompatActivity {
307 publisherEntity.setPublishUrl(publisherSuccess); 308 publisherEntity.setPublishUrl(publisherSuccess);
308 String pamp= new Gson().toJson(publisherEntity); 309 String pamp= new Gson().toJson(publisherEntity);
309 XdyLogUtil.e("推流成功",""+pamp); 310 XdyLogUtil.e("推流成功",""+pamp);
310 - XdySdk.setAsyncApi("publishVideo",pamp); 311 + XdySdk.api("publishVideo",pamp);
311 } 312 }
312 313
313 } 314 }
@@ -317,11 +318,18 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -317,11 +318,18 @@ public class AudioPublisherActivity extends AppCompatActivity {
317 } 318 }
318 319
319 } 320 }
  321 + /**
  322 + * 测试Audio
  323 + */
  324 + public void publisherAudioText(){
  325 + XdySdk.api(Constants.PUBLISH_AUDIO, "", surfaceview_pubisherVideo, AudioPublisherActivity.this,"");
  326 +
  327 + }
320 328
321 @Override 329 @Override
322 public void onBackPressed() { 330 public void onBackPressed() {
323 331
324 - XdySdk.setAsyncApi("unPublishVideo",""); 332 + XdySdk.api("unPublishVideo","");
325 super.onBackPressed(); 333 super.onBackPressed();
326 } 334 }
327 335
@@ -347,15 +355,16 @@ public class AudioPublisherActivity extends AppCompatActivity { @@ -347,15 +355,16 @@ public class AudioPublisherActivity extends AppCompatActivity {
347 break; 355 break;
348 case R.id.btn_videoPlay_publisherAudio: 356 case R.id.btn_videoPlay_publisherAudio:
349 //获取推流地址推送音频 357 //获取推流地址推送音频
350 - getPublish();  
351 - isPusherAudio=true;  
352 - XdySdk.onPublisherStop();  
353 - ToastUtil.showToastshort("推送音频",AudioPublisherActivity.this);  
354 - btn_videoPlay_publisherAudio.setClickable(false); 358 +// getPublish();
  359 +// isPusherAudio=true;
  360 +// XdySdk.onPublisherStop();
  361 +// ToastUtil.showToastshort("推送音频",AudioPublisherActivity.this);
  362 +// btn_videoPlay_publisherAudio.setClickable(false);
  363 + publisherAudioText();
355 break; 364 break;
356 case R.id.btn_videoPlay_stop: 365 case R.id.btn_videoPlay_stop:
357 ToastUtil.showToastshort("正在退出,请稍等",this); 366 ToastUtil.showToastshort("正在退出,请稍等",this);
358 - XdySdk.setAsyncApi("unPublishVideo",""); 367 + XdySdk.api("unPublishVideo","");
359 finish(); 368 finish();
360 break; 369 break;
361 } 370 }
@@ -4,6 +4,8 @@ import android.app.AlertDialog; @@ -4,6 +4,8 @@ import android.app.AlertDialog;
4 import android.app.Dialog; 4 import android.app.Dialog;
5 import android.content.Context; 5 import android.content.Context;
6 import android.content.DialogInterface; 6 import android.content.DialogInterface;
  7 +import android.graphics.Bitmap;
  8 +import android.graphics.BitmapFactory;
7 import android.media.Image; 9 import android.media.Image;
8 import android.os.Bundle; 10 import android.os.Bundle;
9 import android.os.Handler; 11 import android.os.Handler;
@@ -24,6 +26,7 @@ import android.widget.ImageView; @@ -24,6 +26,7 @@ import android.widget.ImageView;
24 import android.widget.TextView; 26 import android.widget.TextView;
25 import android.widget.Toast; 27 import android.widget.Toast;
26 28
  29 +import com.bumptech.glide.Glide;
27 import com.eventhandle.SmartEventCallback; 30 import com.eventhandle.SmartEventCallback;
28 import com.google.gson.Gson; 31 import com.google.gson.Gson;
29 import com.mang.xdy.core.XdySdk; 32 import com.mang.xdy.core.XdySdk;
@@ -37,12 +40,17 @@ import com.mang.xdy.demo.bean.InitClassSuccessEntity; @@ -37,12 +40,17 @@ import com.mang.xdy.demo.bean.InitClassSuccessEntity;
37 import com.mang.xdy.demo.bean.JoinClass; 40 import com.mang.xdy.demo.bean.JoinClass;
38 import com.mang.xdy.demo.bean.LiveBean; 41 import com.mang.xdy.demo.bean.LiveBean;
39 import com.mang.xdy.demo.bean.VideoPlayBean; 42 import com.mang.xdy.demo.bean.VideoPlayBean;
  43 +import com.mang.xdy.demo.bean.WhiteboardUpdateEntity;
40 import com.mang.xdy.demo.utils.JsonUtil; 44 import com.mang.xdy.demo.utils.JsonUtil;
41 import com.mang.xdy.demo.utils.ToastUtil; 45 import com.mang.xdy.demo.utils.ToastUtil;
  46 +import com.mang.xdy.demo.widget.CanvasView;
42 import com.mang.xdy.utils.XdyLogUtil; 47 import com.mang.xdy.utils.XdyLogUtil;
43 import com.mang.xdy.utils.XdyStringUtils; 48 import com.mang.xdy.utils.XdyStringUtils;
44 import com.squareup.picasso.Picasso; 49 import com.squareup.picasso.Picasso;
45 50
  51 +import java.io.IOException;
  52 +import java.util.concurrent.ExecutionException;
  53 +
46 import butterknife.BindView; 54 import butterknife.BindView;
47 import butterknife.ButterKnife; 55 import butterknife.ButterKnife;
48 import butterknife.OnClick; 56 import butterknife.OnClick;
@@ -73,7 +81,16 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -73,7 +81,16 @@ public class VideoPlayActivity extends AppCompatActivity {
73 private TabLayout tabLayout; 81 private TabLayout tabLayout;
74 @BindView(R.id.surfaceview_playVideo) 82 @BindView(R.id.surfaceview_playVideo)
75 SurfaceView surfaceviewPlayVideo; 83 SurfaceView surfaceviewPlayVideo;
  84 + @BindView(R.id.canvas_playVideo_showWhiteBroad)
  85 + CanvasView mCanvasView;
76 private String initClass = ""; 86 private String initClass = "";
  87 + public OnAcceptFromCoreToFragmentListener mOnAcceptFromCoreToFragmentListener;
  88 + public interface OnAcceptFromCoreToFragmentListener{
  89 + void onAcceptInfo(String type,String response);
  90 + }
  91 + public void setmOnAcceptFromCoreToFragmentListener(OnAcceptFromCoreToFragmentListener mOnAcceptFromCoreToFragmentListener){
  92 + this.mOnAcceptFromCoreToFragmentListener=mOnAcceptFromCoreToFragmentListener;
  93 + }
77 private Handler handler = new Handler() { 94 private Handler handler = new Handler() {
78 @Override 95 @Override
79 public void handleMessage(Message msg) { 96 public void handleMessage(Message msg) {
@@ -85,7 +102,7 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -85,7 +102,7 @@ public class VideoPlayActivity extends AppCompatActivity {
85 break; 102 break;
86 case -1: 103 case -1:
87 //退出 104 //退出
88 - XdySdk.setAsyncApi("leaveClass", ""); 105 + XdySdk.api("leaveClass", "");
89 break; 106 break;
90 case 0: 107 case 0:
91 parseJoinClass((String) msg.obj,true); 108 parseJoinClass((String) msg.obj,true);
@@ -114,7 +131,7 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -114,7 +131,7 @@ public class VideoPlayActivity extends AppCompatActivity {
114 getMsg((String) msg.obj); 131 getMsg((String) msg.obj);
115 break; 132 break;
116 case 6: 133 case 6:
117 - //推流video 134 + //图片
118 setDocImage((String) msg.obj); 135 setDocImage((String) msg.obj);
119 break; 136 break;
120 case 7: 137 case 7:
@@ -134,8 +151,9 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -134,8 +151,9 @@ public class VideoPlayActivity extends AppCompatActivity {
134 super.onCreate(savedInstanceState); 151 super.onCreate(savedInstanceState);
135 setContentView(R.layout.activity_video_play); 152 setContentView(R.layout.activity_video_play);
136 ButterKnife.bind(this); 153 ButterKnife.bind(this);
137 -// setTablayout(); 154 +
138 init(); 155 init();
  156 + setTablayout();
139 XdyLogUtil.e(TAG,"当前线程 main:"+android.os.Process.myPid()+"线程:"+Thread.currentThread().getId()+""); 157 XdyLogUtil.e(TAG,"当前线程 main:"+android.os.Process.myPid()+"线程:"+Thread.currentThread().getId()+"");
140 XdySdk.setOnXdyAsyncMessageLitener(new XdySdk.OnXdyAsyncMessageLitener() { 158 XdySdk.setOnXdyAsyncMessageLitener(new XdySdk.OnXdyAsyncMessageLitener() {
141 @Override 159 @Override
@@ -191,8 +209,9 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -191,8 +209,9 @@ public class VideoPlayActivity extends AppCompatActivity {
191 break; 209 break;
192 case "whiteboard_annotation_update": 210 case "whiteboard_annotation_update":
193 ToastUtil.showToastshort("白板信息更新" + response, VideoPlayActivity.this); 211 ToastUtil.showToastshort("白板信息更新" + response, VideoPlayActivity.this);
  212 + showDoc(type,response);
194 break; 213 break;
195 - case "live": 214 + case "getDocImageFullPath":
196 // String urls= "rtmp://player.daniulive.com:1935/hls/stream";; 215 // String urls= "rtmp://player.daniulive.com:1935/hls/stream";;
197 //推流直播 216 //推流直播
198 Message message6=Message.obtain(); 217 Message message6=Message.obtain();
@@ -206,18 +225,21 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -206,18 +225,21 @@ public class VideoPlayActivity extends AppCompatActivity {
206 break; 225 break;
207 case "audio_stop": 226 case "audio_stop":
208 227
209 - break; 228 + break;
210 default:{ 229 default:{
211 XdyLogUtil.e("xuedianyunlog",response); 230 XdyLogUtil.e("xuedianyunlog",response);
212 } 231 }
213 } 232 }
  233 + if(mOnAcceptFromCoreToFragmentListener!=null){
  234 + mOnAcceptFromCoreToFragmentListener.onAcceptInfo(type,response);
  235 + }
214 } 236 }
215 }); 237 });
216 } 238 }
217 239
218 public void init() { 240 public void init() {
219 initClass = getIntent().getStringExtra("init"); 241 initClass = getIntent().getStringExtra("init");
220 - XdySdk.setAsyncApi("init", initClass); 242 + XdySdk.api("init", initClass);
221 243
222 } 244 }
223 245
@@ -261,7 +283,7 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -261,7 +283,7 @@ public class VideoPlayActivity extends AppCompatActivity {
261 String temp=new Gson().toJson(joinClass); 283 String temp=new Gson().toJson(joinClass);
262 String jsonParmp = XdyStringUtils.stringToJson(temp, true); 284 String jsonParmp = XdyStringUtils.stringToJson(temp, true);
263 XdyLogUtil.e("加入课堂", jsonParmp); 285 XdyLogUtil.e("加入课堂", jsonParmp);
264 - XdySdk.setAsyncApi("joinClass", jsonParmp); 286 + XdySdk.api("joinClass", jsonParmp);
265 } 287 }
266 VideoPlayBean videoPlayBean; 288 VideoPlayBean videoPlayBean;
267 public void playVideo(String response) { 289 public void playVideo(String response) {
@@ -270,7 +292,7 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -270,7 +292,7 @@ public class VideoPlayActivity extends AppCompatActivity {
270 // XdyLogUtil.e(TAG, "执行了ss" + videoPlayBean.getRtmpUrl()); 292 // XdyLogUtil.e(TAG, "执行了ss" + videoPlayBean.getRtmpUrl());
271 bt_stop.setEnabled(true); 293 bt_stop.setEnabled(true);
272 // XdySdk.setAsyncApi("playVideo", videoPlayBean.getRtmpUrl(), surfaceviewPlayVideo, VideoPlayActivity.this, new EventHande_Video()); 294 // XdySdk.setAsyncApi("playVideo", videoPlayBean.getRtmpUrl(), surfaceviewPlayVideo, VideoPlayActivity.this, new EventHande_Video());
273 - XdySdk.setAsyncApi("playVideo", response+"", surfaceviewPlayVideo, VideoPlayActivity.this,""); 295 + XdySdk.api("playVideo", response+"", surfaceviewPlayVideo, VideoPlayActivity.this,"");
274 img_playVideo_novideo.setVisibility(View.GONE); 296 img_playVideo_novideo.setVisibility(View.GONE);
275 // }else{ 297 // }else{
276 // bt_stop.setEnabled(false); 298 // bt_stop.setEnabled(false);
@@ -283,7 +305,7 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -283,7 +305,7 @@ public class VideoPlayActivity extends AppCompatActivity {
283 // if (audioPlayBean != null && audioPlayBean.getRtmpUrl() != null) { 305 // if (audioPlayBean != null && audioPlayBean.getRtmpUrl() != null) {
284 // XdyLogUtil.e(TAG, "执行了" + audioPlayBean.getRtmpUrl()); 306 // XdyLogUtil.e(TAG, "执行了" + audioPlayBean.getRtmpUrl());
285 // XdySdk.setAsyncApi("playAudio", audioPlayBean.getRtmpUrl(), null, VideoPlayActivity.this, new EventHande_Video()); 307 // XdySdk.setAsyncApi("playAudio", audioPlayBean.getRtmpUrl(), null, VideoPlayActivity.this, new EventHande_Video());
286 - XdySdk.setAsyncApi("playAudio", response, null, VideoPlayActivity.this, ""); 308 + XdySdk.api("playAudio", response, null, VideoPlayActivity.this, "");
287 img_playVideo_novideo.setVisibility(View.GONE); 309 img_playVideo_novideo.setVisibility(View.GONE);
288 ToastUtil.showToastshort("音频播放初始化",VideoPlayActivity.this); 310 ToastUtil.showToastshort("音频播放初始化",VideoPlayActivity.this);
289 // } 311 // }
@@ -312,7 +334,7 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -312,7 +334,7 @@ public class VideoPlayActivity extends AppCompatActivity {
312 getDocImageEntity.setType("jpg"); 334 getDocImageEntity.setType("jpg");
313 String jsonParmp = new Gson().toJson(getDocImageEntity); 335 String jsonParmp = new Gson().toJson(getDocImageEntity);
314 XdyLogUtil.e(TAG, "文档" + jsonParmp); 336 XdyLogUtil.e(TAG, "文档" + jsonParmp);
315 - XdySdk.setAsyncApi("getDocImageFullPath", jsonParmp); 337 + XdySdk.api("getDocImageFullPath", jsonParmp);
316 } 338 }
317 } 339 }
318 340
@@ -323,7 +345,7 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -323,7 +345,7 @@ public class VideoPlayActivity extends AppCompatActivity {
323 "}"; 345 "}";
324 String jsonParmp = XdyStringUtils.stringToJson(temp, true); 346 String jsonParmp = XdyStringUtils.stringToJson(temp, true);
325 XdyLogUtil.e(TAG, "聊天" + jsonParmp); 347 XdyLogUtil.e(TAG, "聊天" + jsonParmp);
326 - XdySdk.setAsyncApi("sendChatMsg", jsonParmp); 348 + XdySdk.api("sendChatMsg", jsonParmp);
327 349
328 } 350 }
329 351
@@ -338,35 +360,9 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -338,35 +360,9 @@ public class VideoPlayActivity extends AppCompatActivity {
338 360
339 //获取推流地址 361 //获取推流地址
340 public void getPublish() { 362 public void getPublish() {
341 -// String ids_new = "getVideoPublishPath";  
342 -// String tem = "{ \"type\": \"live\"}";  
343 -// String s = XdyStringUtils.stringToJson(tem, true);  
344 -// XdySdk.setAsyncApi(ids_new, s);  
345 } 363 }
346 364
347 public void publisherVideo(String response) { 365 public void publisherVideo(String response) {
348 -// XdySdk.onPlayStop();  
349 -// String url = XdyStringUtils.stringToJson(response);  
350 -// XdyLogUtil.e("调用任务了播视频了url:", "" + url);  
351 -// String us = response.substring(1, response.length() - 1);  
352 -// XdyLogUtil.e("调用任务了播视频了ursfdfl:", "" + us);  
353 -// try {  
354 -// LiveBean liveBean = new Gson().fromJson(url, LiveBean.class);  
355 -//  
356 -// if (liveBean != null&&liveBean.getCode()==0) {  
357 -// String url_text="rtmp://player.daniulive.com:1935/hls/stream";  
358 -//// XdySdk.setAsyncApi("publishVideo", liveBean.getPublishUrl(), surfaceviewPlayVideo, VideoPlayActivity.this,new EventHande());  
359 -//// tv_videoPlay_url.setText("推流地址:"+liveBean.getPublishUrl());  
360 -// tv_videoPlay_url.setText("推流地址:"+url_text);  
361 -// XdyLogUtil.e(TAG,liveBean.getPublishUrl());  
362 -// XdySdk.setAsyncApi("publishVideo", url_text, surfaceview_pubisherVideo, VideoPlayActivity.this,new EventHande());  
363 -// ToastUtil.showToastshort("推流初始化中",VideoPlayActivity.this);  
364 -// }  
365 -// } catch (Exception e) {  
366 -// XdyLogUtil.e("调用任务了播视频了e", "" + e.getMessage());  
367 -//  
368 -// }  
369 -  
370 } 366 }
371 367
372 @Override 368 @Override
@@ -390,78 +386,11 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -390,78 +386,11 @@ public class VideoPlayActivity extends AppCompatActivity {
390 case R.id.bt_stop: 386 case R.id.bt_stop:
391 //停止视频 387 //停止视频
392 if(videoPlayBean!=null) { 388 if(videoPlayBean!=null) {
393 - XdySdk.setAsyncApi("stopVideo", videoPlayBean.getMediaId() + ""); 389 + XdySdk.api("stopVideo", videoPlayBean.getMediaId() + "");
394 } 390 }
395 break; 391 break;
396 } 392 }
397 } 393 }
398 - class EventHande implements SmartEventCallback {  
399 - @Override  
400 - public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {  
401 - switch (code) {  
402 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:  
403 - Log.i(TAG, "开始。。");  
404 - break;  
405 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:  
406 - Log.i(TAG, "连接中。。");  
407 - break;  
408 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:  
409 - Log.i(TAG, "连接失败。。");  
410 - break;  
411 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:  
412 - Log.i(TAG, "连接成功。。");  
413 - //TODO  
414 - break;  
415 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:  
416 - Log.i(TAG, "连接断开。。");  
417 - break;  
418 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:  
419 - Log.i(TAG, "关闭。。");  
420 - break;  
421 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:  
422 - Log.i(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);  
423 - break;  
424 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:  
425 - Log.i(TAG, "收不到媒体数据,可能是url错误。。");  
426 - }  
427 -  
428 - }  
429 - }  
430 -  
431 -  
432 - class EventHande_Video implements SmartEventCallback {  
433 - @Override  
434 - public void onCallback(int code, long param1, long param2, String param3, String param4, Object param5) {  
435 - switch (code) {  
436 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:  
437 - Log.i(TAG, "开始。。");  
438 - break;  
439 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:  
440 - Log.i(TAG, "连接中。。");  
441 - break;  
442 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:  
443 - Log.i(TAG, "连接失败。。");  
444 - break;  
445 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:  
446 - Log.i(TAG, "连接成功。。");  
447 -  
448 - //TODO  
449 - break;  
450 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:  
451 - Log.i(TAG, "连接断开。。");  
452 - break;  
453 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_STOP:  
454 - Log.i(TAG, "关闭。。");  
455 - break;  
456 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:  
457 - Log.i(TAG, "分辨率信息: width: " + param1 + ", height: " + param2);  
458 - break;  
459 - case EVENTID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:  
460 - Log.i(TAG, "收不到媒体数据,可能是url错误。。");  
461 - }  
462 -  
463 - }  
464 - }  
465 class PersonDialog extends Dialog { 394 class PersonDialog extends Dialog {
466 public PersonDialog(Context context) { 395 public PersonDialog(Context context) {
467 this(context, false); 396 this(context, false);
@@ -528,9 +457,54 @@ public class VideoPlayActivity extends AppCompatActivity { @@ -528,9 +457,54 @@ public class VideoPlayActivity extends AppCompatActivity {
528 if(resonse.length()>10){ 457 if(resonse.length()>10){
529 String temp=XdyStringUtils.stringToJson(resonse); 458 String temp=XdyStringUtils.stringToJson(resonse);
530 String url=temp.substring(2,temp.length()-2); 459 String url=temp.substring(2,temp.length()-2);
  460 + urlsss=url;
531 XdyLogUtil.e(TAG,"截取后的"+url); 461 XdyLogUtil.e(TAG,"截取后的"+url);
532 - Picasso.with(this).load(url).placeholder(R.mipmap.novideo).into(mDocImage); 462 + Picasso.with(this).load(url).placeholder(R.mipmap.novideo).into(mDocImage);
  463 + getBitmap(url);
  464 + }
  465 + }
  466 + String urlsss="";
  467 + Bitmap bitmap;
  468 + public void showDoc(String type,String response){
  469 + mCanvasView.setZOrderMediaOverlay(true);
  470 + mCanvasView.setBitmap(bitmap,false);
  471 +
  472 + WhiteboardUpdateEntity whiteboardUpdateEntity= JsonUtil.parseJsonToBean(response,WhiteboardUpdateEntity.class);
  473 + if(whiteboardUpdateEntity!=null){
  474 + drawline(whiteboardUpdateEntity);
  475 + }
  476 +
  477 + }
  478 + private void drawline(WhiteboardUpdateEntity o) {
  479 + if (o != null) {
  480 + if (o.isFresh) {
  481 + if (mCanvasView != null) {
  482 + mCanvasView.clear();
  483 + }
  484 + }
  485 +
  486 + if (o.annotaionItems != null) {
  487 + if (mCanvasView != null) {
  488 + mCanvasView.drawLine(o.annotaionItems);
  489 + }
  490 + }
533 491
534 } 492 }
535 } 493 }
  494 +
  495 + public void getBitmap(final String url){
  496 + new Thread(){
  497 + @Override
  498 + public void run() {
  499 + super.run();
  500 + try {
  501 + bitmap= Glide.with(VideoPlayActivity.this).load(url).asBitmap().into(480,480).get();
  502 + } catch (InterruptedException e) {
  503 + e.printStackTrace();
  504 + } catch (ExecutionException e) {
  505 + e.printStackTrace();
  506 + }
  507 + }
  508 + }.start();
  509 + }
536 } 510 }
@@ -93,7 +93,7 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -93,7 +93,7 @@ public class VideoPublisherActivity extends AppCompatActivity {
93 break; 93 break;
94 case -1: 94 case -1:
95 //退出 95 //退出
96 - XdySdk.setAsyncApi("leaveClass", ""); 96 + XdySdk.api("leaveClass", "");
97 break; 97 break;
98 case 0: 98 case 0:
99 parseJoinClass((String) msg.obj,true); 99 parseJoinClass((String) msg.obj,true);
@@ -191,7 +191,7 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -191,7 +191,7 @@ public class VideoPublisherActivity extends AppCompatActivity {
191 191
192 public void init() { 192 public void init() {
193 initClass = getIntent().getStringExtra("init"); 193 initClass = getIntent().getStringExtra("init");
194 - XdySdk.setAsyncApi("init", initClass); 194 + XdySdk.api("init", initClass);
195 195
196 } 196 }
197 //判断解析是否有密码 197 //判断解析是否有密码
@@ -226,14 +226,14 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -226,14 +226,14 @@ public class VideoPublisherActivity extends AppCompatActivity {
226 String temp=new Gson().toJson(joinClass); 226 String temp=new Gson().toJson(joinClass);
227 String jsonParmp = XdyStringUtils.stringToJson(temp, true); 227 String jsonParmp = XdyStringUtils.stringToJson(temp, true);
228 XdyLogUtil.e("加入课堂", jsonParmp); 228 XdyLogUtil.e("加入课堂", jsonParmp);
229 - XdySdk.setAsyncApi("joinClass", jsonParmp); 229 + XdySdk.api("joinClass", jsonParmp);
230 } 230 }
231 231
232 public void playVideo(String response) { 232 public void playVideo(String response) {
233 VideoPlayBean videoPlayBean = JsonUtil.parseJsonToBean(response, VideoPlayBean.class); 233 VideoPlayBean videoPlayBean = JsonUtil.parseJsonToBean(response, VideoPlayBean.class);
234 if (videoPlayBean != null && videoPlayBean.getRtmpUrl() != null) 234 if (videoPlayBean != null && videoPlayBean.getRtmpUrl() != null)
235 XdyLogUtil.e(TAG, "执行了ss" + videoPlayBean.getRtmpUrl()); 235 XdyLogUtil.e(TAG, "执行了ss" + videoPlayBean.getRtmpUrl());
236 - XdySdk.setAsyncApi("playVideo", videoPlayBean.getRtmpUrl(), surfaceviewPlayVideo, VideoPublisherActivity.this, new EventHande_Video()); 236 + XdySdk.api("playVideo", videoPlayBean.getRtmpUrl(), surfaceviewPlayVideo, VideoPublisherActivity.this, new EventHande_Video());
237 // img_playVideo_novideo.setVisibility(View.GONE); 237 // img_playVideo_novideo.setVisibility(View.GONE);
238 ToastUtil.showToastshort("视频播放初始化",VideoPublisherActivity.this); 238 ToastUtil.showToastshort("视频播放初始化",VideoPublisherActivity.this);
239 } 239 }
@@ -242,7 +242,7 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -242,7 +242,7 @@ public class VideoPublisherActivity extends AppCompatActivity {
242 AudioPlayBean audioPlayBean = JsonUtil.parseJsonToBean(response, AudioPlayBean.class); 242 AudioPlayBean audioPlayBean = JsonUtil.parseJsonToBean(response, AudioPlayBean.class);
243 if (audioPlayBean != null && audioPlayBean.getRtmpUrl() != null) { 243 if (audioPlayBean != null && audioPlayBean.getRtmpUrl() != null) {
244 XdyLogUtil.e(TAG, "执行了" + audioPlayBean.getRtmpUrl()); 244 XdyLogUtil.e(TAG, "执行了" + audioPlayBean.getRtmpUrl());
245 - XdySdk.setAsyncApi("playAudio", audioPlayBean.getRtmpUrl(), null, VideoPublisherActivity.this, new EventHande_Video()); 245 + XdySdk.api("playAudio", audioPlayBean.getRtmpUrl(), null, VideoPublisherActivity.this, new EventHande_Video());
246 // img_playVideo_novideo.setVisibility(View.GONE); 246 // img_playVideo_novideo.setVisibility(View.GONE);
247 ToastUtil.showToastshort("音频播放初始化",VideoPublisherActivity.this); 247 ToastUtil.showToastshort("音频播放初始化",VideoPublisherActivity.this);
248 } 248 }
@@ -267,7 +267,7 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -267,7 +267,7 @@ public class VideoPublisherActivity extends AppCompatActivity {
267 267
268 String jsonParmp = XdyStringUtils.stringToJson(temp, true); 268 String jsonParmp = XdyStringUtils.stringToJson(temp, true);
269 XdyLogUtil.e(TAG, "文档" + jsonParmp); 269 XdyLogUtil.e(TAG, "文档" + jsonParmp);
270 - XdySdk.setAsyncApi("getDocImageFullPath", jsonParmp); 270 + XdySdk.api("getDocImageFullPath", jsonParmp);
271 } 271 }
272 } 272 }
273 273
@@ -278,7 +278,7 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -278,7 +278,7 @@ public class VideoPublisherActivity extends AppCompatActivity {
278 "}"; 278 "}";
279 String jsonParmp = XdyStringUtils.stringToJson(temp, true); 279 String jsonParmp = XdyStringUtils.stringToJson(temp, true);
280 XdyLogUtil.e(TAG, "聊天" + jsonParmp); 280 XdyLogUtil.e(TAG, "聊天" + jsonParmp);
281 - XdySdk.setAsyncApi("sendChatMsg", jsonParmp); 281 + XdySdk.api("sendChatMsg", jsonParmp);
282 282
283 } 283 }
284 284
@@ -296,14 +296,14 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -296,14 +296,14 @@ public class VideoPublisherActivity extends AppCompatActivity {
296 String ids_new = "getVideoPublishPath"; 296 String ids_new = "getVideoPublishPath";
297 String tem = "{ \"type\": \"live\"}"; 297 String tem = "{ \"type\": \"live\"}";
298 String s = XdyStringUtils.stringToJson(tem, true); 298 String s = XdyStringUtils.stringToJson(tem, true);
299 - XdySdk.setAsyncApi(ids_new, s); 299 + XdySdk.api(ids_new, s);
300 } 300 }
301 301
302 /** 302 /**
303 * 获取封装的推流地址 303 * 获取封装的推流地址
304 */ 304 */
305 public void publisherVideoText(){ 305 public void publisherVideoText(){
306 -// XdySdk.setAsyncApi("publishVideo", "", surfaceview_pubisherVideo, VideoPublisherActivity.this,""); 306 + XdySdk.api("publishVideo", "", surfaceview_pubisherVideo, VideoPublisherActivity.this,"");
307 307
308 } 308 }
309 309
@@ -311,7 +311,7 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -311,7 +311,7 @@ public class VideoPublisherActivity extends AppCompatActivity {
311 * 测试Audio 311 * 测试Audio
312 */ 312 */
313 public void publisherAudioText(){ 313 public void publisherAudioText(){
314 - XdySdk.setAsyncApi(Constants.PUBLISH_AUDIO, "", surfaceview_pubisherVideo, VideoPublisherActivity.this,""); 314 +// XdySdk.setAsyncApi(Constants.PUBLISH_AUDIO, "", surfaceview_pubisherVideo, VideoPublisherActivity.this,"");
315 315
316 } 316 }
317 public void publisherVideo(String response) { 317 public void publisherVideo(String response) {
@@ -325,10 +325,10 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -325,10 +325,10 @@ public class VideoPublisherActivity extends AppCompatActivity {
325 // String url_text="rtmp://123.56.205.116:6000/live/h5dev_1999957388_980_983041_1491813919"; 325 // String url_text="rtmp://123.56.205.116:6000/live/h5dev_1999957388_980_983041_1491813919";
326 publisherSuccess=liveBean.getPublishUrl(); 326 publisherSuccess=liveBean.getPublishUrl();
327 if(isPusherAudio){ 327 if(isPusherAudio){
328 - XdySdk.setAsyncApi("publishAudio", liveBean.getPublishUrl(), surfaceview_pubisherVideo, VideoPublisherActivity.this,new EventHande()); 328 + XdySdk.api("publishAudio", liveBean.getPublishUrl(), surfaceview_pubisherVideo, VideoPublisherActivity.this,new EventHande());
329 ToastUtil.showToastshort("推送纯音频初始化中",VideoPublisherActivity.this); 329 ToastUtil.showToastshort("推送纯音频初始化中",VideoPublisherActivity.this);
330 }else{ 330 }else{
331 - XdySdk.setAsyncApi("publishVideo", liveBean.getPublishUrl(), surfaceview_pubisherVideo, VideoPublisherActivity.this,new EventHande()); 331 + XdySdk.api("publishVideo", liveBean.getPublishUrl(), surfaceview_pubisherVideo, VideoPublisherActivity.this,new EventHande());
332 ToastUtil.showToastshort("推送视频初始化中",VideoPublisherActivity.this); 332 ToastUtil.showToastshort("推送视频初始化中",VideoPublisherActivity.this);
333 } 333 }
334 isAbleback=true; 334 isAbleback=true;
@@ -338,7 +338,7 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -338,7 +338,7 @@ public class VideoPublisherActivity extends AppCompatActivity {
338 publisherEntity.setPublishUrl(publisherSuccess); 338 publisherEntity.setPublishUrl(publisherSuccess);
339 String pamp= new Gson().toJson(publisherEntity); 339 String pamp= new Gson().toJson(publisherEntity);
340 XdyLogUtil.e("推流成功",""+pamp); 340 XdyLogUtil.e("推流成功",""+pamp);
341 - XdySdk.setAsyncApi("publishVideo",pamp); 341 + XdySdk.api("publishVideo",pamp);
342 } 342 }
343 343
344 } 344 }
@@ -352,12 +352,7 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -352,12 +352,7 @@ public class VideoPublisherActivity extends AppCompatActivity {
352 @Override 352 @Override
353 public void onBackPressed() { 353 public void onBackPressed() {
354 //退出课堂 354 //退出课堂
355 -  
356 -//  
357 -//// ToastUtil.showToastshort("正在退出,请稍等",this);  
358 -// PublisherVideoExitBean publisherVideoExitBean = new PublisherVideoExitBean();  
359 -// publisherVideoExitBean.setMediaId(publisherVideoExitBean.getMediaId());  
360 - XdySdk.setAsyncApi("unPublishVideo",""); 355 + XdySdk.api("unPublishVideo","");
361 super.onBackPressed(); 356 super.onBackPressed();
362 357
363 358
@@ -379,22 +374,15 @@ public class VideoPublisherActivity extends AppCompatActivity { @@ -379,22 +374,15 @@ public class VideoPublisherActivity extends AppCompatActivity {
379 break; 374 break;
380 case R.id.btn_videoPlay_pubsherVideo: 375 case R.id.btn_videoPlay_pubsherVideo:
381 // getPublish(); 376 // getPublish();
382 -// publisherVideoText();  
383 - publisherAudioText(); 377 + publisherVideoText();
  378 +// publisherAudioText();
384 ToastUtil.showToastshort("推送视频",VideoPublisherActivity.this); 379 ToastUtil.showToastshort("推送视频",VideoPublisherActivity.this);
385 btnVideoPlayPubsherVideo.setClickable(false); 380 btnVideoPlayPubsherVideo.setClickable(false);
386 - break;  
387 - case R.id.btn_videoPlay_publisherAudio:  
388 - //获取推流地址推送音频  
389 -// getPublish();  
390 -// isPusherAudio=true;  
391 -// XdySdk.onPublisherStop();  
392 -// ToastUtil.showToastshort("推送音频",VideoPublisherActivity.this);  
393 -// btn_videoPlay_publisherAudio.setClickable(false); 381 +
394 break; 382 break;
395 case R.id.btn_videoPlay_stop: 383 case R.id.btn_videoPlay_stop:
396 ToastUtil.showToastshort("正在退出,请稍等",this); 384 ToastUtil.showToastshort("正在退出,请稍等",this);
397 - XdySdk.setAsyncApi("unPublishVideo",""); 385 + XdySdk.api("unPublishVideo","");
398 finish(); 386 finish();
399 break; 387 break;
400 } 388 }
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.adapter;
  17 +
  18 +import android.widget.AbsListView;
  19 +import android.widget.ImageView;
  20 +
  21 +
  22 +import com.mang.xdy.demo.R;
  23 +import com.mang.xdy.demo.bean.Faceicon;
  24 +
  25 +import org.kymjs.kjframe.KJBitmap;
  26 +import org.kymjs.kjframe.widget.AdapterHolder;
  27 +import org.kymjs.kjframe.widget.KJAdapter;
  28 +
  29 +import java.util.Collection;
  30 +
  31 +/**
  32 + * 表情区域GridView的适配器
  33 + *
  34 + * @author kymjs (http://www.kymjs.com/)
  35 + */
  36 +public class FaceAdapter extends KJAdapter<Faceicon> {
  37 + private KJBitmap kjb = new KJBitmap();
  38 +
  39 + public FaceAdapter(AbsListView view, Collection<Faceicon> mDatas) {
  40 + super(view, mDatas, R.layout.home_chat_item_face);
  41 + }
  42 +
  43 + @Override
  44 + public void convert(AdapterHolder adapterHolder, Faceicon data, boolean b) {
  45 + ImageView view = adapterHolder.getView(R.id.itemImage);
  46 +// int id = view.getResources().getIdentifier(s,
  47 +// "drawable", view.getContext().getPackageName());
  48 +// view.setImageResource(id);
  49 + kjb.display(view, data.getPath());
  50 + }
  51 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.adapter;
  17 +
  18 +import android.graphics.Bitmap;
  19 +import android.os.Bundle;
  20 +import android.support.v4.app.Fragment;
  21 +import android.support.v4.app.FragmentManager;
  22 +import android.support.v4.app.FragmentStatePagerAdapter;
  23 +import android.widget.ImageView;
  24 +
  25 +
  26 +import com.mang.xdy.demo.R;
  27 +import com.mang.xdy.demo.widget.chat.ChatFunctionFragment;
  28 +import com.mang.xdy.demo.widget.chat.FacePageFragment;
  29 +import com.mang.xdy.demo.widget.chat.KJChatKeyboard;
  30 +import com.mang.xdy.demo.widget.chat.OnOperationListener;
  31 +import com.mang.xdy.demo.widget.chat.PagerSlidingTabStrip;
  32 +import com.mang.xdy.demo.widget.emoji.EmojiPageFragment;
  33 +
  34 +import org.kymjs.kjframe.bitmap.BitmapCreate;
  35 +
  36 +import java.io.File;
  37 +import java.util.List;
  38 +
  39 +/**
  40 + * 控件分类的viewpager适配器
  41 + *
  42 + * @author kymjs (http://www.kymjs.com/)
  43 + */
  44 +public class FaceCategroyAdapter extends FragmentStatePagerAdapter implements
  45 + PagerSlidingTabStrip.IconTabProvider {
  46 + private final int sMode;
  47 +
  48 + //每个item表示一个folder绝对路径,每个folder中存放的是一套face图片
  49 + private List<String> datas;
  50 + private OnOperationListener listener;
  51 +
  52 + public FaceCategroyAdapter(FragmentManager fm, int mode) {
  53 + super(fm);
  54 + sMode = mode;
  55 + }
  56 +
  57 + @Override
  58 + public void setPageIcon(int position, ImageView image) {
  59 + if (position == 0) {
  60 + image.setImageResource(R.mipmap.emoji_normal);
  61 + return;
  62 + }
  63 + File file = new File(datas.get(position - 1));
  64 + String path = null;
  65 + for (int i = 0; i < file.list().length; i++) {
  66 + path = file.list()[i];
  67 + if (path.endsWith(".png") || path.endsWith(".jpg") || path.endsWith(".jpeg")) {
  68 + break;
  69 + }
  70 + }
  71 + Bitmap bitmap = BitmapCreate.bitmapFromFile(file.getAbsolutePath() + "/" + path, 40, 40);
  72 + image.setImageBitmap(bitmap);
  73 + }
  74 +
  75 + @Override
  76 + public int getCount() {
  77 + if (sMode == KJChatKeyboard.LAYOUT_TYPE_FACE) {
  78 + int count = datas == null ? 0 : datas.size();
  79 + //加1是因为有默认的emoji表情分类
  80 + return (count + 1);
  81 + } else {
  82 + return 1;
  83 + }
  84 + }
  85 +
  86 + @Override
  87 + public Fragment getItem(int position) {
  88 + Fragment f = null;
  89 + if (sMode == KJChatKeyboard.LAYOUT_TYPE_FACE) {
  90 + if (position == 0) {
  91 + f = new EmojiPageFragment();
  92 + ((EmojiPageFragment) f).setOnOperationListener(listener);
  93 + } else {
  94 + position--;
  95 + f = new FacePageFragment();
  96 + ((FacePageFragment) f).setOnOperationListener(listener);
  97 + Bundle bundle = new Bundle();
  98 + bundle.putString(FacePageFragment.FACE_FOLDER_PATH, datas.get(position));
  99 + f.setArguments(bundle);
  100 + }
  101 + } else {
  102 + f = new ChatFunctionFragment();
  103 + ((ChatFunctionFragment) f).setOnOperationListener(listener);
  104 + }
  105 + return f;
  106 + }
  107 +
  108 + public void setOnOperationListener(OnOperationListener onOperationListener) {
  109 + this.listener = onOperationListener;
  110 + }
  111 +
  112 + public void refresh(List<String> datas) {
  113 + this.datas = datas;
  114 + notifyDataSetChanged();
  115 + }
  116 +}
@@ -9,27 +9,37 @@ import android.support.v4.app.Fragment; @@ -9,27 +9,37 @@ import android.support.v4.app.Fragment;
9 import android.support.v4.app.FragmentManager; 9 import android.support.v4.app.FragmentManager;
10 import android.support.v4.app.FragmentPagerAdapter; 10 import android.support.v4.app.FragmentPagerAdapter;
11 11
  12 +import com.mang.xdy.demo.fragment.ChatFragment;
  13 +import com.mang.xdy.demo.fragment.DocFragment;
12 import com.mang.xdy.demo.fragment.PageFragment; 14 import com.mang.xdy.demo.fragment.PageFragment;
13 15
  16 +import java.util.ArrayList;
  17 +import java.util.List;
  18 +
14 public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter { 19 public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {
15 20
16 - final int PAGE_COUNT = 3;  
17 - private String tabTitles[] = new String[]{"tab1","tab2","tab3"}; 21 + final int PAGE_COUNT = 1;
  22 + private String tabTitles[] = new String[]{"tab1","tab2"};
18 private Context context; 23 private Context context;
19 - 24 + private DocFragment docFragment=new DocFragment();
  25 + private ChatFragment chatFragment=new ChatFragment();
  26 + private List<Fragment> fragmentList=new ArrayList<>();
20 public SimpleFragmentPagerAdapter(FragmentManager fm,Context context) { 27 public SimpleFragmentPagerAdapter(FragmentManager fm,Context context) {
21 super(fm); 28 super(fm);
22 this.context = context; 29 this.context = context;
  30 + fragmentList.add(docFragment);
  31 + fragmentList.add(chatFragment);
23 } 32 }
24 33
25 @Override 34 @Override
26 public Fragment getItem(int position) { 35 public Fragment getItem(int position) {
27 - return PageFragment.newInstance(position + 1); 36 +// return PageFragment.newInstance(position + 1);
  37 + return fragmentList.get(position);
28 } 38 }
29 39
30 @Override 40 @Override
31 public int getCount() { 41 public int getCount() {
32 - return PAGE_COUNT; 42 + return fragmentList.size();
33 } 43 }
34 44
35 @Override 45 @Override
@@ -5,6 +5,7 @@ import android.app.Application; @@ -5,6 +5,7 @@ import android.app.Application;
5 import android.content.Context; 5 import android.content.Context;
6 6
7 import com.mang.xdy.core.XdySdk; 7 import com.mang.xdy.core.XdySdk;
  8 +import com.mang.xdy.demo.utils.ResUtil;
8 9
9 /** 10 /**
10 * Created by abao on 2017/3/30. 11 * Created by abao on 2017/3/30.
@@ -18,6 +19,7 @@ public class XdyApplicaiton extends Application { @@ -18,6 +19,7 @@ public class XdyApplicaiton extends Application {
18 super.onCreate(); 19 super.onCreate();
19 context=this; 20 context=this;
20 XdySdk.init(this); 21 XdySdk.init(this);
  22 + ResUtil.init(this);
21 } 23 }
22 public static Activity getActivity(){ 24 public static Activity getActivity(){
23 return activityList; 25 return activityList;
  1 +package com.mang.xdy.demo.bean;
  2 +
  3 +import java.util.List;
  4 +import java.util.List;
  5 +
  6 +/**
  7 + * Created by Admin on 2017/3/27.
  8 + */
  9 +
  10 +public class AnnotaionEntity {
  11 + public String type;
  12 + public String itemIdx;
  13 + public String initiator;
  14 + public String parentId;
  15 + public String curPageNo;
  16 + public List<PointGroupEntity> pointGroup;
  17 + public String color;
  18 + public int thickness;
  19 + public String radius;
  20 + public String fontSize;
  21 + public String fontName;
  22 + public String text;
  23 + public String data;
  24 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.bean;
  17 +
  18 +import java.io.Serializable;
  19 +
  20 +/**
  21 + * 表情javabean
  22 + * @author kymjs (http://www.kymjs.com/) on 6/9/15.
  23 + */
  24 +public class Faceicon implements Serializable {
  25 + private String name; //网络传输中的值
  26 + private String path; //在系统中的绝对路径
  27 + private String fileName; //图片文件名
  28 +
  29 + public String getName() {
  30 + return name;
  31 + }
  32 +
  33 + public void setName(String name) {
  34 + this.name = name;
  35 + }
  36 +
  37 + public String getPath() {
  38 + return path;
  39 + }
  40 +
  41 + public void setPath(String path) {
  42 + this.path = path;
  43 + }
  44 +
  45 + public String getFileName() {
  46 + return fileName;
  47 + }
  48 +
  49 + public void setFileName(String fileName) {
  50 + this.fileName = fileName;
  51 + }
  52 +}
  1 +package com.mang.xdy.demo.bean;
  2 +
  3 +/**
  4 + * Created by Admin on 2017/3/27.
  5 + */
  6 +
  7 +public class PointGroupEntity {
  8 + public float w;
  9 + public float h;
  10 +
  11 + @Override
  12 + public Object clone() throws CloneNotSupportedException {
  13 + return super.clone();
  14 + }
  15 +}
  1 +package com.mang.xdy.demo.bean;
  2 +
  3 +/**
  4 + * Created by Admin on 2017/3/26.
  5 + */
  6 +
  7 +public class PointXY {
  8 + public float x;
  9 + public float y;
  10 +}
  1 +package com.mang.xdy.demo.bean;
  2 +
  3 +import java.util.List;
  4 +
  5 +/** 书写板更新事件entity
  6 + * Created by Admin on 2017/3/27.
  7 + */
  8 +
  9 +public class WhiteboardUpdateEntity {
  10 +
  11 + public boolean isFresh; //是否先清除,true(先清除再绘制),false(在现有的基础上添加绘制)
  12 + public List<AnnotaionEntity> annotaionItems; //需要显示的标注标注内容数组(包含不同的type类型)
  13 +}
  1 +package com.mang.xdy.demo.fragment;
  2 +
  3 +import android.content.Context;
  4 +import android.os.Bundle;
  5 +import android.support.annotation.Nullable;
  6 +import android.support.v4.app.Fragment;
  7 +import android.text.Selection;
  8 +import android.text.Spannable;
  9 +import android.text.TextUtils;
  10 +import android.view.LayoutInflater;
  11 +import android.view.MotionEvent;
  12 +import android.view.View;
  13 +import android.view.ViewGroup;
  14 +
  15 +import com.mang.xdy.demo.R;
  16 +import com.mang.xdy.demo.bean.Faceicon;
  17 +import com.mang.xdy.demo.widget.chat.KJChatKeyboard;
  18 +import com.mang.xdy.demo.widget.chat.OnOperationListener;
  19 +
  20 +import java.io.File;
  21 +import java.math.MathContext;
  22 +import java.util.ArrayList;
  23 +import java.util.List;
  24 +
  25 +import butterknife.BindView;
  26 +import butterknife.ButterKnife;
  27 +
  28 +/**
  29 + * Created by abao on 2017/4/17.
  30 + */
  31 +
  32 +public class ChatFragment extends Fragment {
  33 + @BindView(R.id.chat_msg_input_box)
  34 + KJChatKeyboard box;
  35 + private Context mContext;
  36 + @Nullable
  37 + @Override
  38 + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  39 + View view=inflater.inflate(R.layout.fragment_chat,container,false);
  40 + ButterKnife.bind(this,view);
  41 + return view;
  42 + }
  43 +
  44 + @Override
  45 + public void onActivityCreated(@Nullable Bundle savedInstanceState) {
  46 + super.onActivityCreated(savedInstanceState);
  47 + mContext=this.getContext();
  48 + init();
  49 + }
  50 +
  51 + public void init(){
  52 + box.setToolBoxIsClick(false);
  53 + box.setOnOperationListener(new OnOperationListener() {
  54 + @Override
  55 + public void send(String content) {
  56 + if (!TextUtils.isEmpty(content)) {
  57 +// LogUtil.i("聊天内容===" + content);
  58 +// mPresenter.sendChatMsg(content, 0);
  59 + }
  60 +
  61 + }
  62 +
  63 + @Override
  64 + public void selectedFace(Faceicon content) {
  65 + /* Message message = new Message(Message.MSG_TYPE_FACE, Message.MSG_STATE_SUCCESS,
  66 + "Tom", "avatar", "Jerry", "avatar", content.getPath(), true, true, new
  67 + Date());
  68 + datas.add(message);
  69 + adapter.refresh(datas);*/
  70 +
  71 + }
  72 +
  73 + @Override
  74 + public void selectedEmoji(String emoji) {
  75 + if (!TextUtils.isEmpty(emoji)) {
  76 + int start = box.getEditTextBox().getSelectionStart();
  77 + CharSequence content = box.getEditTextBox().getText().insert(start, emoji);
  78 + box.getEditTextBox().setText(content);
  79 + // 定位光标位置
  80 + CharSequence info = box.getEditTextBox().getText();
  81 + if (info instanceof Spannable) {
  82 + Spannable spanText = (Spannable) info;
  83 + Selection.setSelection(spanText, start + emoji.length());
  84 + }
  85 + box.setEditTextFocus();
  86 + }
  87 + }
  88 +
  89 + @Override
  90 + public void selectedBackSpace(String back) {
  91 +// DisplayRules.backspace(box.getEditTextBox());
  92 + }
  93 +
  94 + @Override
  95 + public void selectedFunction(int index) {
  96 + switch (index) {
  97 + case 0:
  98 + // goToAlbum();
  99 + break;
  100 + case 1:
  101 + // ViewInject.toast("跳转相机");
  102 + break;
  103 + }
  104 + }
  105 + });
  106 + List<String> faceCagegory = new ArrayList<>();
  107 +// File faceList = FileUtils.getSaveFolder("chat");
  108 + File faceList = new File("");
  109 + if (faceList.isDirectory()) {
  110 + File[] faceFolderArray = faceList.listFiles();
  111 + for (File folder : faceFolderArray) {
  112 + if (!folder.isHidden()) {
  113 + faceCagegory.add(folder.getAbsolutePath());
  114 + }
  115 + }
  116 + }
  117 +
  118 + box.setFaceData(faceCagegory);
  119 +// mRealListView.setOnTouchListener(getOnTouchListener());
  120 + }
  121 +
  122 +
  123 + /**
  124 + * 若软键盘或表情键盘弹起,点击上端空白处应该隐藏输入法键盘
  125 + *
  126 + * @return 会隐藏输入法键盘的触摸事件监听器
  127 + */
  128 + private View.OnTouchListener getOnTouchListener() {
  129 + return new View.OnTouchListener() {
  130 + @Override
  131 + public boolean onTouch(View v, MotionEvent event) {
  132 + box.hideLayout();
  133 + box.hideKeyboard(mContext);
  134 + return false;
  135 + }
  136 + };
  137 + }
  138 +}
  1 +package com.mang.xdy.demo.fragment;
  2 +
  3 +import android.content.Context;
  4 +import android.graphics.Bitmap;
  5 +import android.graphics.BitmapFactory;
  6 +import android.os.Bundle;
  7 +import android.os.Handler;
  8 +import android.os.Message;
  9 +import android.support.annotation.Nullable;
  10 +import android.support.v4.app.Fragment;
  11 +import android.view.LayoutInflater;
  12 +import android.view.View;
  13 +import android.view.ViewGroup;
  14 +
  15 +import com.bumptech.glide.Glide;
  16 +import com.google.gson.Gson;
  17 +import com.mang.xdy.common.Constants;
  18 +import com.mang.xdy.core.XdySdk;
  19 +import com.mang.xdy.demo.R;
  20 +import com.mang.xdy.demo.activity.VideoPlayActivity;
  21 +import com.mang.xdy.demo.bean.DocEntity;
  22 +import com.mang.xdy.demo.bean.GetDocImageEntity;
  23 +import com.mang.xdy.demo.bean.WhiteboardUpdateEntity;
  24 +import com.mang.xdy.demo.utils.JsonUtil;
  25 +import com.mang.xdy.demo.widget.CanvasView;
  26 +import com.mang.xdy.utils.XdyLogUtil;
  27 +import com.mang.xdy.utils.XdyStringUtils;
  28 +import com.squareup.picasso.Picasso;
  29 +
  30 +import java.util.concurrent.ExecutionException;
  31 +
  32 +import butterknife.BindView;
  33 +import butterknife.ButterKnife;
  34 +
  35 +/**
  36 + * Created by abao on 2017/4/14.
  37 + */
  38 +
  39 +public class DocFragment extends Fragment implements VideoPlayActivity.OnAcceptFromCoreToFragmentListener{
  40 + private static String TAG="DocFragment";
  41 + @BindView(R.id.canvas_doc_show)
  42 + CanvasView mCanvasView;
  43 + private Bitmap bitmap;
  44 + private Context mContext;
  45 + private String whritebroad="";
  46 +
  47 + @Override
  48 + public void onActivityCreated(@Nullable Bundle savedInstanceState) {
  49 + super.onActivityCreated(savedInstanceState);
  50 + init();
  51 + mContext=this.getContext();
  52 + }
  53 +
  54 + private static Handler mHandler=new Handler(){
  55 + @Override
  56 + public void handleMessage(Message msg) {
  57 + super.handleMessage(msg);
  58 +
  59 + }
  60 + };
  61 +
  62 + @Nullable
  63 + @Override
  64 + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  65 + View view=inflater.inflate(R.layout.fragment_doc,container,false);
  66 + ButterKnife.bind(this,view);
  67 + return view;
  68 + }
  69 +
  70 + public void init(){
  71 + VideoPlayActivity videoPlayActivity= (VideoPlayActivity) this.getActivity();
  72 + mCanvasView.setBitmap(getEmptyBitmap(),false);
  73 + videoPlayActivity.setmOnAcceptFromCoreToFragmentListener(this);
  74 +
  75 + }
  76 +
  77 +
  78 + public void getDoc(String response) {
  79 + DocEntity docEntity = JsonUtil.parseJsonToBean(response, DocEntity.class);
  80 + if (docEntity != null && docEntity.getRelativeUrl() != null) {
  81 + String url = docEntity.getRelativeUrl();
  82 + GetDocImageEntity getDocImageEntity=new GetDocImageEntity();
  83 + getDocImageEntity.setPageNum(1);
  84 +// getDocImageEntity.setRelativeUrl("/DocSharing/data/1087553281/20170409-204600041/d32594763768243bddc64934be5088a0.swf");
  85 + getDocImageEntity.setRelativeUrl(url);
  86 + getDocImageEntity.setType("jpg");
  87 + String jsonParmp = new Gson().toJson(getDocImageEntity);
  88 + XdyLogUtil.e(TAG, "文档" + jsonParmp);
  89 + XdySdk.api("getDocImageFullPath", jsonParmp);
  90 + }
  91 + }
  92 +
  93 + public void setDocImage(String resonse){
  94 + if(resonse.length()>10){
  95 + String temp= XdyStringUtils.stringToJson(resonse);
  96 + String url=temp.substring(2,temp.length()-2);
  97 + XdyLogUtil.e(TAG,"截取后的"+url);
  98 + getBitmap(url);
  99 + }
  100 + }
  101 +
  102 + public void getBitmap(final String url){
  103 + new Thread(){
  104 + @Override
  105 + public void run() {
  106 + super.run();
  107 + try {
  108 + bitmap= Glide.with(mContext).load(url).asBitmap().into(480,480).get();
  109 + if(bitmap!=null) {
  110 + mHandler.post(new Runnable() {
  111 + @Override
  112 + public void run() {
  113 + mCanvasView.setBitmap(bitmap,false);
  114 + }
  115 + });
  116 +
  117 + }
  118 + } catch (InterruptedException e) {
  119 + e.printStackTrace();
  120 + } catch (ExecutionException e) {
  121 + e.printStackTrace();
  122 + }
  123 + }
  124 + }.start();
  125 + }
  126 + /**
  127 + * 展示文档
  128 + * @param type
  129 + * @param response
  130 + */
  131 + public void showDoc(String type,String response){
  132 + mCanvasView.setZOrderMediaOverlay(true);
  133 +
  134 + if(bitmap!=null) {
  135 + mCanvasView.setBitmap(bitmap,false);
  136 + }
  137 +// else{
  138 +// mCanvasView.setBitmap(getEmptyBitmap(),false);
  139 +// }
  140 + WhiteboardUpdateEntity whiteboardUpdateEntity= JsonUtil.parseJsonToBean(response,WhiteboardUpdateEntity.class);
  141 + if(whiteboardUpdateEntity!=null){
  142 + drawline(whiteboardUpdateEntity);
  143 +
  144 + }
  145 +
  146 + }
  147 + public Bitmap getEmptyBitmap(){
  148 + Bitmap bitmap_empty= BitmapFactory.decodeResource(getResources(),R.mipmap.no_doc);
  149 +
  150 + return bitmap_empty;
  151 + }
  152 +
  153 +
  154 +
  155 +
  156 + private void drawline(WhiteboardUpdateEntity o) {
  157 + if (o != null) {
  158 + if (o.isFresh) {
  159 + if (mCanvasView != null) {
  160 + mCanvasView.clear();
  161 + }
  162 + }
  163 +
  164 + if (o.annotaionItems != null) {
  165 + if (mCanvasView != null) {
  166 + mCanvasView.drawLine(o.annotaionItems);
  167 + }
  168 + }
  169 + }
  170 + }
  171 +
  172 +
  173 + @Override
  174 + public void onAcceptInfo(String type, String response) {
  175 + XdyLogUtil.e(TAG,"type:"+type+" response:"+response);
  176 + switch (type){
  177 + case Constants.DOCUMENT_UPDATE:
  178 + getDoc(response);
  179 + break;
  180 + case "getDocImageFullPath":
  181 + setDocImage(response);
  182 + break;
  183 + case Constants.WHITEBOARD_ANNOTATION_UPDATE:
  184 + showDoc(type,response);
  185 + break;
  186 + case Constants.DOCUMENT_DELETE:
  187 + bitmap=null;
  188 + mCanvasView.setBitmap(getEmptyBitmap(),false);
  189 + break;
  190 +
  191 + }
  192 + }
  193 +}
  1 +package com.mang.xdy.demo.utils;
  2 +
  3 +import android.annotation.SuppressLint;
  4 +import android.app.Activity;
  5 +import android.content.Context;
  6 +import android.content.res.Resources;
  7 +import android.graphics.Rect;
  8 +import android.util.DisplayMetrics;
  9 +import android.view.View;
  10 +import android.view.Window;
  11 +import android.view.WindowManager;
  12 +
  13 +import java.lang.reflect.Field;
  14 +import java.lang.reflect.InvocationTargetException;
  15 +import java.lang.reflect.Method;
  16 +
  17 +import android.annotation.SuppressLint;
  18 +import android.app.Activity;
  19 +import android.content.Context;
  20 +import android.content.res.Resources;
  21 +import android.graphics.Rect;
  22 +import android.util.DisplayMetrics;
  23 +import android.view.View;
  24 +import android.view.Window;
  25 +import android.view.WindowManager;
  26 +
  27 +import java.lang.reflect.Field;
  28 +import java.lang.reflect.InvocationTargetException;
  29 +import java.lang.reflect.Method;
  30 +
  31 +/**
  32 + * @version 1.0
  33 + * @file DisplayUtil.java
  34 + * @brief 获得当前手机一些屏幕信息
  35 + * @date 2017/9/22
  36 + * Copyright (c) 2017, 学点云
  37 + * All rights reserved.
  38 + */
  39 +public class DisplayUtil {
  40 +
  41 + /**
  42 + * 获得不同手机状态栏高度
  43 + * @param ctx
  44 + * @return
  45 + */
  46 + public static int getStatusBarHeight(Context ctx) {
  47 +
  48 + Class<?> c = null;
  49 +
  50 + Object obj = null;
  51 +
  52 + Field field = null;
  53 +
  54 + int x = 0, statusBarHeight = 0;
  55 +
  56 + try {
  57 +
  58 + c = Class.forName("com.android.internal.R$dimen");
  59 +
  60 + obj = c.newInstance();
  61 +
  62 + field = c.getField("status_bar_height");
  63 +
  64 + x = Integer.parseInt(field.get(obj).toString());
  65 +
  66 + statusBarHeight = ctx.getResources().getDimensionPixelOffset(x);
  67 +
  68 + } catch (Exception e1) {
  69 + e1.printStackTrace();
  70 + }
  71 + return statusBarHeight;
  72 + }
  73 +
  74 + /**
  75 + * 魅族手机判断是否有SmartBar 并隐藏SmartBar
  76 + * @return
  77 + */
  78 + @SuppressWarnings("unused")
  79 + public static boolean judgeBar() {
  80 + boolean isHasBar = false;
  81 + try {
  82 + try {
  83 + Method method = Class.forName("android.os.Build").getMethod(
  84 + "hasSmartBar");
  85 + isHasBar = ((Boolean) method.invoke(null)).booleanValue();
  86 + } catch (IllegalArgumentException e) {
  87 + e.printStackTrace();
  88 + } catch (IllegalAccessException e) {
  89 + e.printStackTrace();
  90 + } catch (InvocationTargetException e) {
  91 + e.printStackTrace();
  92 + }
  93 + } catch (NoSuchMethodException e) {
  94 + e.printStackTrace();
  95 + } catch (ClassNotFoundException e) {
  96 + e.printStackTrace();
  97 + }
  98 + return isHasBar;
  99 + }
  100 +
  101 + /**
  102 + * 全屏显示。。
  103 + */
  104 + @SuppressLint("NewApi")
  105 + public static void getFullScrean(Activity ctx) {
  106 + Window mWindow = ctx.getWindow();
  107 + WindowManager.LayoutParams params = mWindow.getAttributes();
  108 + params.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
  109 + mWindow.setAttributes(params);
  110 + }
  111 +
  112 + /**
  113 + * @param ctx
  114 + * @brief 获得屏幕像素密度
  115 + */
  116 + public static float getScreenDensity(Context ctx) {
  117 + WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
  118 + DisplayMetrics displayMetrics = new DisplayMetrics();
  119 + wm.getDefaultDisplay().getMetrics(displayMetrics);
  120 + return displayMetrics.density;
  121 + }
  122 +
  123 + /**
  124 + * @param context
  125 + * @param dipValue
  126 + * @return
  127 + * @brief DP转像素
  128 + */
  129 + public static int dip2px(Context context, float dipValue) {
  130 + final float scale = context.getResources().getDisplayMetrics().density;
  131 + return (int) (dipValue * scale + 0.5f);
  132 + }
  133 +
  134 + /**
  135 + * @param context
  136 + * @param
  137 + * @return
  138 + * @brief 像素转DP
  139 + */
  140 + public static int px2dip(Context context, float pxValue) {
  141 + final float scale = context.getResources().getDisplayMetrics().density;
  142 + return (int) (pxValue / scale + 0.5f);
  143 + }
  144 +
  145 + /**
  146 + * 是否有导航栏
  147 + * @param context
  148 + * @return
  149 + */
  150 + private static boolean checkDeviceHasNavigationBar(Context context) {
  151 + boolean hasNavigationBar = false;
  152 + Resources rs = context.getResources();
  153 + int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
  154 + if (id > 0) {
  155 + hasNavigationBar = rs.getBoolean(id);
  156 + }
  157 + try {
  158 + Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
  159 + Method m = systemPropertiesClass.getMethod("get", String.class);
  160 + String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
  161 + if ("1".equals(navBarOverride)) {
  162 + hasNavigationBar = false;
  163 + } else if ("0".equals(navBarOverride)) {
  164 + hasNavigationBar = true;
  165 + }
  166 + } catch (Exception e) {
  167 + e.printStackTrace();
  168 + }
  169 + return hasNavigationBar;
  170 + }
  171 +
  172 + /**
  173 + * @param context
  174 + * @return
  175 + * @brief 获取导航栏(虚拟按键高度)
  176 + */
  177 + public static int getNavigationBarHeight(Context context) {
  178 + int navigationBarHeight = 0;
  179 + Resources rs = context.getResources();
  180 + int id = rs.getIdentifier("navigation_bar_height", "dimen", "android");
  181 + if (id > 0 && checkDeviceHasNavigationBar(context)) {
  182 + navigationBarHeight = rs.getDimensionPixelSize(id);
  183 + }
  184 + return navigationBarHeight;
  185 + }
  186 +
  187 + private static DisplayMetrics dm = null;
  188 +
  189 + public static int getScreenWidth(Context context) {
  190 + return getScreenWidthInPx(context);
  191 + }
  192 +
  193 + public static int getScreenHeight(Context context) {
  194 + return getScreenHeightInPx(context);
  195 + }
  196 +
  197 +
  198 + static public DisplayMetrics getDisplayMetrics(Context context) {
  199 + if (dm == null) {
  200 + dm = context.getResources().getDisplayMetrics();
  201 + }
  202 + return dm;
  203 + }
  204 +
  205 + static public int px2dp(Context context, int px) {
  206 + if (context == null) {
  207 + return px;
  208 + }
  209 + getDisplayMetrics(context);
  210 + final float density = dm.density;
  211 + return (int) (px / density + 0.5f);
  212 + }
  213 +
  214 + static public int dp2px(Context context, float dp) {
  215 + if (context == null) {
  216 + return (int) dp;
  217 + }
  218 + getDisplayMetrics(context);
  219 + final float density = dm.density;
  220 + return (int) (dp * density + 0.5f);
  221 + }
  222 +
  223 + static public int px2sp(Context context, float px) {
  224 + if (context == null) {
  225 + return (int) px;
  226 + }
  227 + getDisplayMetrics(context);
  228 + return (int) (px / dm.scaledDensity + 0.5f);
  229 + }
  230 +
  231 + static public int sp2px(Context context, float sp) {
  232 + if (context == null) {
  233 + return (int) sp;
  234 + }
  235 + getDisplayMetrics(context);
  236 + return (int) (sp * dm.scaledDensity + 0.5f);
  237 + }
  238 +
  239 + static public int getScreenWidthInPx(Context context) {
  240 + getDisplayMetrics(context);
  241 + return dm.widthPixels;
  242 + }
  243 +
  244 + static public int getScreenHeightInPx(Context context) {
  245 + getDisplayMetrics(context);
  246 + return dm.heightPixels;
  247 + }
  248 +
  249 + static public int getScreenWidthInDp(Context context) {
  250 + getDisplayMetrics(context);
  251 + return (int) ((float) dm.widthPixels * (160 / dm.xdpi));
  252 + }
  253 +
  254 + static public int getScreenHeightInDp(Context context) {
  255 + getDisplayMetrics(context);
  256 + int screenHeight = dm.heightPixels;
  257 + return (int) ((float) screenHeight / dm.density);
  258 + }
  259 +
  260 + static public float getDensity(Context context) {
  261 + getDisplayMetrics(context);
  262 + return dm.density;
  263 + }
  264 +
  265 + public static int getScreenTitleBarHeight(Context context) {
  266 + Rect rect = new Rect();
  267 + ((Activity) context).getWindow().getDecorView()
  268 + .getWindowVisibleDisplayFrame(rect);
  269 + return rect.top;
  270 + }
  271 +}
  1 +package com.mang.xdy.demo.utils;
  2 +
  3 +import android.content.Context;
  4 +import android.content.res.Resources;
  5 +import android.support.annotation.StringRes;
  6 +
  7 +import java.io.BufferedReader;
  8 +import java.io.IOException;
  9 +import java.io.InputStream;
  10 +import java.io.InputStreamReader;
  11 +
  12 +import android.content.Context;
  13 +import android.content.res.Resources;
  14 +import android.support.annotation.StringRes;
  15 +
  16 +import java.io.BufferedReader;
  17 +import java.io.IOException;
  18 +import java.io.InputStream;
  19 +import java.io.InputStreamReader;
  20 +
  21 +
  22 +/**
  23 + * @version 1.0
  24 + * @file ResUtil.java
  25 + * @brief 封装了获取资源的一些方法,方便的获得字符串,颜色等资源
  26 + * @date 2017/6/4
  27 + * Copyright (c) 2017
  28 + * All rights reserved.
  29 + */
  30 +public class ResUtil {
  31 +
  32 + private static Context ctx;
  33 +
  34 + private ResUtil() {
  35 + }
  36 +
  37 + public static void init(Context cc) {
  38 + ctx = cc;
  39 + }
  40 +
  41 + public static ResUtil get() {
  42 + return SingletonHolder.INSTANCE;
  43 + }
  44 +
  45 + private static class SingletonHolder {
  46 + private static final ResUtil INSTANCE = new ResUtil();
  47 + }
  48 +
  49 + /**
  50 + * @return Resources
  51 + * @brief 获得当前APP的Resource的方法
  52 + */
  53 + public static Resources getResource() {
  54 + return ctx.getResources();
  55 + }
  56 +
  57 + /**
  58 + * 获取字符串
  59 + * @param stringId
  60 + * @return
  61 + */
  62 + public String getString(@StringRes int stringId) {
  63 + return getResource().getString(stringId);
  64 + }
  65 +
  66 + /**
  67 + * 获取字符串,带格式化方法
  68 + * @param stringId
  69 + * @param formatArgs
  70 + * @return
  71 + */
  72 + public String getString(int stringId, Object... formatArgs) {
  73 + return getResource().getString(stringId, formatArgs);
  74 + }
  75 +
  76 + /**
  77 + * 获取Dimen值对应的像素值
  78 + * @param dimenId
  79 + * @return
  80 + */
  81 + public int getDimenPixel(int dimenId) {
  82 + return getResource().getDimensionPixelOffset(dimenId);
  83 + }
  84 +
  85 + /**
  86 + * 获取颜色
  87 + * @param colorId
  88 + * @return
  89 + */
  90 + public int getColor(int colorId) {
  91 + return getResource().getColor(colorId);
  92 + }
  93 +
  94 + /**
  95 + * 获取资产中的字符串
  96 + * @param fileName
  97 + * @return
  98 + */
  99 + public String getStringFromAssert(String fileName) {
  100 + InputStream in = null;
  101 + try {
  102 + in = getResource().getAssets().open(fileName);
  103 + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
  104 + String line = null;
  105 + StringBuilder sb = new StringBuilder();
  106 + do {
  107 + line = bufferedReader.readLine();
  108 + if (line != null) {
  109 + sb.append(line);
  110 + }
  111 + } while (line != null);
  112 + bufferedReader.close();
  113 + in.close();
  114 + return sb.toString();
  115 + } catch (Exception e) {
  116 + e.printStackTrace();
  117 + } finally {
  118 + if (in != null) {
  119 + try {
  120 + in.close();
  121 + } catch (IOException e) {
  122 + }
  123 + }
  124 + }
  125 + return null;
  126 + }
  127 +}
  1 +package com.mang.xdy.demo.widget;
  2 +
  3 +import android.content.Context;
  4 +import android.graphics.Bitmap;
  5 +import android.graphics.Canvas;
  6 +import android.graphics.Color;
  7 +import android.graphics.Paint;
  8 +import android.graphics.Path;
  9 +import android.graphics.PathEffect;
  10 +import android.graphics.PixelFormat;
  11 +import android.graphics.PointF;
  12 +import android.graphics.Rect;
  13 +import android.util.AttributeSet;
  14 +import android.util.Log;
  15 +import android.view.MotionEvent;
  16 +import android.view.SurfaceHolder;
  17 +import android.view.SurfaceView;
  18 +import android.view.View;
  19 +
  20 +import com.mang.xdy.demo.R;
  21 +import com.mang.xdy.demo.bean.AnnotaionEntity;
  22 +import com.mang.xdy.demo.bean.PointGroupEntity;
  23 +import com.mang.xdy.demo.bean.PointXY;
  24 +import com.mang.xdy.demo.utils.DisplayUtil;
  25 +import com.mang.xdy.demo.utils.ResUtil;
  26 +import com.mang.xdy.utils.XdyLogUtil;
  27 +
  28 +import java.util.ArrayList;
  29 +import java.util.Iterator;
  30 +import java.util.List;
  31 +
  32 +/**
  33 + * Created by Admin on 2017/3/25.
  34 + */
  35 +
  36 +public class CanvasView extends SurfaceView implements SurfaceHolder.Callback, View.OnTouchListener {
  37 +
  38 + private static final int NONE = 0;// 原始
  39 + private static final int DRAG = 1;// 拖动
  40 + private static final int ZOOM = 2;// 放大
  41 + private int mStatus = NONE;
  42 +
  43 + private static final float MAX_ZOOM_SCALE = 4.0f;
  44 + private static final float MIN_ZOOM_SCALE = 1.0f;
  45 + private static final float FLOAT_TYPE = 1.0f;
  46 + private float mCurrentMaxScale = MAX_ZOOM_SCALE;
  47 + private float mCurrentScale = 1.0f;
  48 + // 第一个Rect 代表要绘制的bitmap 区域,第二个 Rect 代表的是要将bitmap 绘制在屏幕的什么地方
  49 +
  50 + private Rect mRectSrc = new Rect(); // used for render image.
  51 + private Rect mRectDes = new Rect(); // used for store size of monitor.
  52 +
  53 + private int mCenterX, mCenterY;
  54 + int mSurfaceHeight, mSurfaceWidth, mImageHeight, mImageWidth;
  55 +
  56 + private PointF mStartPoint = new PointF();
  57 + private float mStartDistance = 0f;
  58 +
  59 + private Bitmap mBitmap;
  60 + private int screenWidth;
  61 + private int currentTop;
  62 + private boolean adjust;
  63 + /**
  64 + * 图片在拖动后的偏移量
  65 + */
  66 + private int currentOffsetY;
  67 +
  68 + private void initRect() {
  69 + mCurrentMaxScale = Math.max(
  70 + MIN_ZOOM_SCALE,
  71 + 4 * Math.min(FLOAT_TYPE * mImageHeight / mSurfaceHeight, 1.0f
  72 + * mImageWidth / mSurfaceWidth));
  73 +
  74 + mCurrentScale = MIN_ZOOM_SCALE;
  75 +
  76 + //最大的缩放比例为图片宽度与屏幕宽度的比例,就是不能缩放
  77 + mCurrentScale = mCurrentMaxScale = (FLOAT_TYPE * screenWidth) / (FLOAT_TYPE * mImageWidth);
  78 +
  79 + mCenterX = mImageWidth / 2;
  80 + mCenterY = mImageHeight / 2;
  81 + calcRect();
  82 + }
  83 +
  84 + private void adjustCenter() {
  85 + int w = mRectSrc.right - mRectSrc.left;
  86 + int h = mRectSrc.bottom - mRectSrc.top;
  87 +
  88 + if (mCenterX - w / 2 < 0) {
  89 + mCenterX = w / 2;
  90 + mRectSrc.left = 0;
  91 + mRectSrc.right = w;
  92 + } else if (mCenterX + w / 2 >= mImageWidth) {
  93 + mCenterX = mImageWidth - w / 2;
  94 + mRectSrc.right = mImageWidth;
  95 + mRectSrc.left = mRectSrc.right - w;
  96 + } else {
  97 + mRectSrc.left = mCenterX - w / 2;
  98 + mRectSrc.right = mRectSrc.left + w;
  99 + }
  100 +
  101 + if (mCenterY - h / 2 < 0) {
  102 + mCenterY = h / 2;
  103 + mRectSrc.top = 0;
  104 + mRectSrc.bottom = h;
  105 + } else if (mCenterY + h / 2 >= mImageHeight) {
  106 + mCenterY = mImageHeight - h / 2;
  107 + mRectSrc.bottom = mImageHeight;
  108 + mRectSrc.top = mRectSrc.bottom - h;
  109 + } else {
  110 + mRectSrc.top = mCenterY - h / 2;
  111 + mRectSrc.bottom = mRectSrc.top + h;
  112 + }
  113 + }
  114 +
  115 + private int finalWidth;
  116 + private int finalHeight;
  117 +
  118 + private void calcRect() {
  119 + int w, h;
  120 + float scaleRatio = ((FLOAT_TYPE * mSurfaceWidth) / (FLOAT_TYPE * mImageWidth));
  121 + finalWidth = w = mSurfaceWidth;
  122 + finalHeight = h = (int) (mImageHeight * scaleRatio);
  123 +
  124 +
  125 + if (adjust) {
  126 + if (finalHeight < mSurfaceHeight && mImageHeight != 0) {
  127 + //比surfaceview高度要小,则放到中间显示
  128 + int top = 0;
  129 + if ((top = (int) ((mSurfaceHeight - finalHeight) / 2 + 0.5f)) != currentTop) {//重新设置path坐标
  130 + currentTop = top;
  131 +
  132 + pathLists.clear();
  133 + this.historyPointer = 0;
  134 + for (List<PointGroupEntity> pointGroupEntities : originPoint) {
  135 +// Path path = new Path();
  136 +// path.addCircle(pointGroupEntities.get(0).w / 100 * finalWidth, pointGroupEntities.get(0).h / 100 * finalWidth + currentTop, annotations.get(0).thickness, Path.Direction.CW);
  137 +// pathLists.add(path);
  138 + pathLists.add(createPath(pointGroupEntities.get(0).w / 100 * finalWidth, pointGroupEntities.get(0).h / 100 * finalWidth + currentTop));
  139 + this.historyPointer++;
  140 + for (int j = 0; j < pointGroupEntities.size(); j++) {
  141 + PointGroupEntity pointGroupEntity = pointGroupEntities.get(j);
  142 + Path p = this.getCurrentPath();
  143 +// p.addCircle(pointGroupEntity.w / 100 * finalWidth, pointGroupEntity.h / 100 * finalWidth + currentTop, annotations.get(0).thickness, Path.Direction.CW);
  144 +
  145 + p.lineTo(pointGroupEntity.w / 100 * finalWidth, pointGroupEntity.h / 100 * finalWidth + currentTop);
  146 + }
  147 + }
  148 + }
  149 + mRectDes.left = 0;
  150 + mRectDes.top = currentTop;
  151 + mRectDes.right = w;
  152 + mRectDes.bottom = h + currentTop;
  153 + } else {
  154 + mRectDes.left = 0;
  155 + mRectDes.top = 0;
  156 + mRectDes.right = w;
  157 + mRectDes.bottom = h;
  158 + }
  159 +
  160 + mCenterX = w / 2;
  161 + mCenterY = h / 2;
  162 +
  163 + mRectSrc.left = 0;
  164 + mRectSrc.top = 0;
  165 + mRectSrc.right = mImageWidth;
  166 + mRectSrc.bottom = mImageHeight;
  167 + } else {
  168 + mRectSrc.left = 0;
  169 + mRectSrc.top = 0;
  170 + mRectSrc.right = mImageWidth;
  171 + mRectSrc.bottom = mImageHeight;
  172 +
  173 + mRectDes.left = (mSurfaceWidth - mImageWidth) / 2;
  174 + mRectDes.top = (mSurfaceHeight - mImageHeight) / 2;
  175 + mRectDes.right = (mSurfaceWidth - mImageWidth) / 2 + mImageWidth;
  176 + mRectDes.bottom = (mSurfaceHeight - mImageHeight) / 2 + mImageHeight;
  177 + }
  178 + }
  179 +
  180 + public void setMaxZoom(float value) {
  181 + mCurrentMaxScale = value;
  182 + }
  183 +
  184 + public void setBitmap(Bitmap b, boolean adjust) {
  185 + //重置数据
  186 + finalHeight = 0;
  187 + finalWidth = 0;
  188 + currentTop = 0;
  189 + currentOffsetY = 0;
  190 + this.adjust = adjust;
  191 + if (b == null) {
  192 + return;
  193 + }
  194 + synchronized (CanvasView.class) {
  195 + mBitmap = b;
  196 + if (mImageHeight != mBitmap.getHeight()
  197 + || mImageWidth != mBitmap.getWidth()) {
  198 + mImageWidth = mBitmap.getWidth();
  199 + mImageHeight = mBitmap.getHeight();
  200 + }
  201 + calcRect();
  202 + drawSurface();
  203 + }
  204 + }
  205 +
  206 + private void dragAction(MotionEvent event) {
  207 +
  208 + synchronized (CanvasView.class) {
  209 + PointF currentPoint = new PointF();
  210 + currentPoint.set(event.getX(), event.getY());
  211 + int offsetX = (int) currentPoint.x - (int) mStartPoint.x;
  212 + int offsetY = (int) currentPoint.y - (int) mStartPoint.y;
  213 + mStartPoint = currentPoint;
  214 +
  215 + mCenterX -= offsetX;
  216 + mCenterY -= offsetY;
  217 +
  218 +
  219 + if (adjust) {
  220 +
  221 +
  222 + if (finalHeight > mSurfaceHeight) {
  223 + int tempTop = mRectDes.top + offsetY;
  224 +
  225 + int deltaTop = 0;
  226 + if (tempTop < mSurfaceHeight - finalHeight) {//过头了
  227 + deltaTop = Math.abs(tempTop) - Math.abs(mSurfaceHeight - finalHeight);//超过的范围,用正整数表达易于理解
  228 + mRectDes.top += (offsetY + deltaTop);
  229 + mRectDes.bottom += (offsetY + deltaTop);
  230 + adjustPath(offsetY + deltaTop);
  231 + } else if (tempTop > 0) {
  232 + mRectDes.top += (offsetY - tempTop);
  233 + mRectDes.bottom += (offsetY - tempTop);
  234 + adjustPath(offsetY - tempTop);
  235 + } else {
  236 + mRectDes.top += offsetY;
  237 + mRectDes.bottom += offsetY;
  238 + adjustPath(offsetY);
  239 + }
  240 + }
  241 + drawSurface();
  242 + }
  243 + }
  244 + }
  245 +
  246 + private void zoomAcition(MotionEvent event) {
  247 +
  248 + synchronized (CanvasView.class) {
  249 +
  250 + float newDist = spacing(event);
  251 + float scale = newDist / mStartDistance;
  252 + mStartDistance = newDist;
  253 +
  254 + mCurrentScale *= scale;
  255 + mCurrentScale = Math.max(FLOAT_TYPE,
  256 + Math.min(mCurrentScale, mCurrentMaxScale));
  257 +
  258 + calcRect();
  259 + adjustCenter();
  260 + drawSurface();
  261 + }
  262 + }
  263 +
  264 + private void adjustPath(int offsetY) {
  265 + currentOffsetY += offsetY;
  266 + pathLists.clear();
  267 + historyPointer = 0;
  268 + //提取原始坐标点
  269 + for (int i = 0; i < operatePoints.size(); i++) {
  270 +
  271 + List<PointGroupEntity> pointGroupEntities = operatePoints.get(i);
  272 +
  273 + //创建一个path并且重新设置七点
  274 + float w = pointGroupEntities.get(0).w;
  275 + float h = pointGroupEntities.get(0).h + (FLOAT_TYPE * offsetY) / (FLOAT_TYPE * finalWidth) * 100f;
  276 + pointGroupEntities.get(0).h = h;
  277 +
  278 +// Path p = new Path();
  279 +// p.addCircle(w / 100f * finalWidth, h / 100f * finalWidth, annotations.get(0).thickness, Path.Direction.CW);
  280 +// pathLists.add(p);
  281 + pathLists.add(createPath(w / 100f * finalWidth, h / 100f * finalWidth));
  282 + historyPointer++;
  283 + for (int j = 1; j < pointGroupEntities.size(); j++) {
  284 + PointGroupEntity pointGroupEntity = pointGroupEntities.get(j);
  285 + Path path = this.getCurrentPath();
  286 + float w2 = pointGroupEntity.w;
  287 + float h2 = pointGroupEntity.h + (FLOAT_TYPE * offsetY) / (FLOAT_TYPE * finalWidth) * 100f;
  288 + pointGroupEntity.h = h2;
  289 + path.lineTo(w2 / 100 * finalWidth, h2 / 100 * finalWidth);
  290 +// path.addCircle(w2 / 100 * finalWidth, h2 / 100 * finalWidth, annotations.get(0).thickness, Path.Direction.CW);
  291 + }
  292 + }
  293 + }
  294 +
  295 + @Override
  296 + public boolean onTouch(View v, MotionEvent event) {
  297 + switch (event.getAction() & MotionEvent.ACTION_MASK) {
  298 + case MotionEvent.ACTION_DOWN:
  299 + mStartPoint.set(event.getX(), event.getY());
  300 + mStatus = DRAG;
  301 + break;
  302 +// case MotionEvent.ACTION_POINTER_DOWN:
  303 +// float distance = spacing(event);
  304 +// if (distance > 10f) {
  305 +//
  306 +// mStatus = ZOOM;
  307 +// mStartDistance = distance;
  308 +// }
  309 +//
  310 +// break;
  311 + case MotionEvent.ACTION_MOVE:
  312 + if (mStatus == DRAG) {
  313 + dragAction(event);
  314 + } else {
  315 +
  316 + if (event.getPointerCount() == 1)
  317 + return true;
  318 + zoomAcition(event);
  319 + }
  320 + break;
  321 + case MotionEvent.ACTION_UP:
  322 + case MotionEvent.ACTION_POINTER_UP:
  323 + mStatus = NONE;
  324 + break;
  325 + default:
  326 + break;
  327 + }
  328 +
  329 + return true;
  330 + }
  331 +
  332 + private float spacing(MotionEvent event) {
  333 + float x = event.getX(0) - event.getX(1);
  334 + float y = event.getY(0) - event.getY(1);
  335 + return (float) Math.sqrt(x * x + y * y);
  336 + }
  337 + ///=================END=================
  338 +
  339 + @Override
  340 + public void surfaceCreated(SurfaceHolder holder) {
  341 + }
  342 +
  343 + boolean isFirst = true;
  344 +
  345 + @Override
  346 + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  347 + Log.i("surfaceview", "change" + "width:" + width + "height:" + height);
  348 +
  349 + synchronized (CanvasView.class) {
  350 + mSurfaceHeight = height;
  351 + mSurfaceWidth = width;
  352 + currentOffsetY = 0;
  353 + calcRect();
  354 +
  355 + operatePoints.clear();
  356 + //重置为最原始坐标
  357 + for (List<PointGroupEntity> pointGroupEntities : originPoint) {
  358 + List<PointGroupEntity> lists = new ArrayList<>();
  359 + for (PointGroupEntity pointXy : pointGroupEntities) {
  360 + PointGroupEntity pointGroupEntity = new PointGroupEntity();
  361 + pointGroupEntity.w = pointXy.w;
  362 + pointGroupEntity.h = pointXy.h;
  363 + lists.add(pointGroupEntity);
  364 + }
  365 + operatePoints.add(lists);
  366 + }
  367 +
  368 + pathLists.clear();
  369 + historyPointer = 0;
  370 + for (List<PointGroupEntity> pointGroupEntities : operatePoints) {
  371 +// Path p = new Path();
  372 +// p.addCircle(pointGroupEntities.get(0).w / 100f * finalWidth, pointGroupEntities.get(0).h / 100f * finalWidth, annotations.get(0).thickness, Path.Direction.CW);
  373 +// pathLists.add(p);
  374 +
  375 + pathLists.add(createPath(pointGroupEntities.get(0).w / 100 * finalWidth, pointGroupEntities.get(0).h / 100 * finalWidth + currentTop));
  376 + historyPointer++;
  377 + for (int i = 1; i < pointGroupEntities.size(); i++) {
  378 + PointGroupEntity pointGroupEntity = pointGroupEntities.get(i);
  379 + Path path = this.getCurrentPath();
  380 + path.lineTo(pointGroupEntity.w / 100 * finalWidth, pointGroupEntity.h / 100 * finalWidth + currentTop);
  381 +// path.addCircle(pointGroupEntity.w / 100 * finalWidth, pointGroupEntity.h / 100 * finalWidth, annotations.get(0).thickness, Path.Direction.CW);
  382 +
  383 + }
  384 +
  385 + }
  386 +
  387 +
  388 + if (mBitmap != null) {
  389 + drawSurface();
  390 + }
  391 + }
  392 + }
  393 +
  394 + @Override
  395 + public void surfaceDestroyed(SurfaceHolder holder) {
  396 +
  397 + }
  398 +
  399 + // Enumeration for Drawer
  400 + public enum Drawer {
  401 + PEN,
  402 + LINE,
  403 + RECTANGLE,
  404 + CIRCLE,
  405 + ELLIPSE,
  406 + QUADRATIC_BEZIER,
  407 + QUBIC_BEZIER;
  408 + }
  409 +
  410 + private SurfaceHolder holder = null; //控制对象
  411 +
  412 + /**
  413 + * 记录最原始的数据
  414 + */
  415 + private List<AnnotaionEntity> annotations = new ArrayList<>();
  416 + private List<List<PointGroupEntity>> originPoint = new ArrayList<>();
  417 + private List<List<PointGroupEntity>> operatePoints = new ArrayList<>();
  418 + private List<Path> pathLists = new ArrayList<Path>();
  419 + private List<Paint> paintLists = new ArrayList<Paint>();
  420 +
  421 + private final Paint emptyPaint = new Paint();
  422 +
  423 + // for Eraser
  424 + private int baseColor = Color.TRANSPARENT;
  425 +
  426 + // for Undo, Redo
  427 + private int historyPointer = 0;
  428 + private Drawer drawer = Drawer.PEN;
  429 +
  430 + // for Paint
  431 + private Paint.Style paintStyle = Paint.Style.STROKE;
  432 + private int paintStrokeColor = Color.BLACK;
  433 + private int paintFillColor = Color.BLACK;
  434 + private float paintStrokeWidth = 3F;///设置线宽
  435 + private int opacity = 255;
  436 + private float blur = 0F;
  437 + private Paint.Cap lineCap = Paint.Cap.ROUND;//笔触风格
  438 + private PathEffect drawPathEffect = null;
  439 +
  440 +
  441 + // for Drawer
  442 + private float startX = 0F;
  443 + private float startY = 0F;
  444 +
  445 +
  446 + public CanvasView(Context context) {
  447 + super(context);
  448 + init();
  449 + }
  450 +
  451 + public CanvasView(Context context, AttributeSet attrs) {
  452 + super(context, attrs);
  453 + init();
  454 + }
  455 +
  456 + public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {
  457 + super(context, attrs, defStyleAttr);
  458 + init();
  459 + }
  460 +
  461 + /**
  462 + * Common initialization.
  463 + */
  464 + private void init() {
  465 + holder = getHolder();
  466 + holder.addCallback(this);
  467 + this.setOnTouchListener(this);
  468 + // 设置背景为透明 否则是黑色
  469 + this.setZOrderOnTop(true);
  470 + // this.setZOrderMediaOverlay(true);
  471 + this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
  472 +
  473 + screenWidth = DisplayUtil.getScreenWidth(getContext());
  474 + }
  475 +
  476 + /**
  477 + * This method creates the instance of Paint.
  478 + * In addition, this method sets styles for Paint.
  479 + * @param color
  480 + * @return paint This is returned as the instance of Paint
  481 + */
  482 + private Paint createPaint(int color, int thickness) {
  483 + Paint paint = new Paint();
  484 +
  485 + paint.setAntiAlias(true);
  486 + paint.setStyle(this.paintStyle);
  487 + paint.setStrokeWidth(thickness);///设置线宽
  488 + paint.setStrokeCap(this.lineCap);
  489 + paint.setStrokeJoin(Paint.Join.ROUND); // fixed
  490 + // Otherwise
  491 + paint.setColor(color);
  492 + paint.setShadowLayer(this.blur, 0F, 0F, this.paintStrokeColor);
  493 + paint.setAlpha(this.opacity);
  494 + paint.setPathEffect(this.drawPathEffect);
  495 +
  496 + return paint;
  497 + }
  498 +
  499 + /**
  500 + * This method initialize Path.
  501 + * Namely, this method creates the instance of Path,
  502 + * and moves current position.
  503 + * @return path This is returned as the instance of Path
  504 + */
  505 + private Path createPath(float x, float y) {
  506 + Path path = new Path();
  507 +
  508 + // Save for ACTION_MOVE
  509 + this.startX = x;
  510 + this.startY = y;
  511 +
  512 + path.rMoveTo(this.startX, this.startY); // 移动的起点坐标
  513 +
  514 + return path;
  515 + }
  516 +
  517 + /**
  518 + * This method gets the instance of Path that pointer indicates.
  519 + * @return the instance of Path
  520 + */
  521 + private Path getCurrentPath() {
  522 + return this.pathLists.get(this.historyPointer - 1);
  523 + }
  524 +
  525 +
  526 + /**
  527 + * This method is setter for drawer.
  528 + * @param drawer
  529 + */
  530 + public void setDrawer(Drawer drawer) {
  531 + this.drawer = drawer;
  532 + }
  533 +
  534 + /**
  535 + * 知道想x,yd的坐标绘制线
  536 + * @param annotations
  537 + */
  538 + public void drawLine(List<AnnotaionEntity> annotations) {
  539 + this.annotations.addAll(annotations);
  540 + for (AnnotaionEntity annotation : annotations) {
  541 + List<PointGroupEntity> pointXies = annotation.pointGroup;
  542 + int color = Color.parseColor(annotation.color);
  543 + setPaintFillColor(color);
  544 + copyArr(pointXies);
  545 + for (PointGroupEntity pointXy : pointXies) {
  546 + float w = pointXy.w;
  547 + float h = pointXy.h + (FLOAT_TYPE * currentOffsetY) / (FLOAT_TYPE * finalWidth) * 100f;
  548 + pointXy.h = h;
  549 + }
  550 +
  551 + //操作一下這個點
  552 + operatePoints.add(pointXies);
  553 +
  554 +// Path path = new Path();
  555 +// path.addCircle(pointXies.get(0).w / 100 * finalWidth, pointXies.get(0).h / 100 * finalWidth + currentTop, annotations.get(0).thickness, Path.Direction.CW);
  556 +// pathLists.add(path);
  557 +
  558 + pathLists.add(createPath(pointXies.get(0).w / 100 * finalWidth, pointXies.get(0).h / 100 * finalWidth + currentTop));
  559 + paintLists.add(this.createPaint(color, annotation.thickness * 2));
  560 + this.historyPointer++;
  561 + for (int i = 0; i < pointXies.size(); i++) {
  562 + Path path = this.getCurrentPath();
  563 +// p.addCircle(pointXies.get(i).w / 100 * finalWidth, pointXies.get(i).h / 100 * finalWidth + currentTop, annotation.thickness, Path.Direction.CW);
  564 +
  565 + path.lineTo(pointXies.get(i).w / 100 * finalWidth, pointXies.get(i).h / 100 * finalWidth + currentTop);
  566 + }
  567 + }
  568 +
  569 + drawSurface();//获取到一个坐标就刷新下界面
  570 + }
  571 +
  572 + private void copyArr(List<PointGroupEntity> pointXies) {
  573 + List<PointGroupEntity> lists = new ArrayList<>();
  574 + for (PointGroupEntity pointXy : pointXies) {
  575 + PointGroupEntity pointGroupEntity = new PointGroupEntity();
  576 + pointGroupEntity.w = pointXy.w;
  577 + pointGroupEntity.h = pointXy.h;
  578 + lists.add(pointGroupEntity);
  579 + }
  580 + originPoint.add(lists);
  581 + }
  582 +
  583 + public void drawRect(List<PointXY> pointXies) {
  584 + Path path = this.getCurrentPath();
  585 + path.reset();
  586 + float startX = pointXies.get(0).x;
  587 + float startY = pointXies.get(0).y;
  588 + for (int i = 0; i < pointXies.size(); i++) {
  589 + float left = Math.min(startX, pointXies.get(i).x);
  590 + float right = Math.max(startX, pointXies.get(i).x);
  591 + float top = Math.min(startY, pointXies.get(i).y);
  592 + float bottom = Math.max(startY, pointXies.get(i).y);
  593 + path.addRect(left, top, right, bottom, Path.Direction.CCW);
  594 + invalidate();
  595 + }
  596 + }
  597 +
  598 + //刷新界面 相当于View里面的 invalidate();
  599 + protected void drawSurface() {
  600 + Canvas canvas = null;
  601 + try {
  602 + canvas = holder.lockCanvas();
  603 +
  604 + //draw bitmap
  605 + if (canvas != null && mBitmap != null) {
  606 + canvas.drawColor(ResUtil.get().getColor(R.color.home_background));
  607 + canvas.drawBitmap(mBitmap, mRectSrc, mRectDes, null);
  608 + for (int i = 0; i < this.historyPointer; i++) {
  609 + Path path = this.pathLists.get(i);
  610 + Paint paint = this.paintLists.get(i);
  611 + canvas.drawPath(path, paint);
  612 + }
  613 + }
  614 + } finally {
  615 + if (canvas != null) {
  616 + holder.unlockCanvasAndPost(canvas);
  617 + }
  618 + }
  619 + }
  620 +
  621 +
  622 + /**
  623 + * 设置画笔的颜色
  624 + * @param color
  625 + */
  626 + public void setPaintFillColor(int color) {
  627 + this.paintFillColor = color;
  628 + }
  629 +
  630 + /**
  631 + * This method initializes canvas.
  632 + * @return
  633 + */
  634 + public void clear() {
  635 + originPoint.clear();
  636 + operatePoints.clear();
  637 + this.pathLists.clear();
  638 + this.paintLists.clear();
  639 + historyPointer = 0;
  640 + }
  641 +
  642 + /**
  643 + * 撤销
  644 + */
  645 + public void redo() {
  646 + if (pathLists.size() > 0) {
  647 +
  648 + Iterator<List<PointGroupEntity>> pointiterator = operatePoints.iterator();
  649 + while (pointiterator.hasNext()) {
  650 + List<PointGroupEntity> next = pointiterator.next();
  651 + if (next == operatePoints.get(operatePoints.size() - 1)) {
  652 + pointiterator.remove();
  653 + }
  654 + }
  655 + Iterator<Path> pathiterator = pathLists.iterator();
  656 + while (pathiterator.hasNext()) {
  657 + Path next = pathiterator.next();
  658 + if (next == pathLists.get(pathLists.size() - 1)) {
  659 + historyPointer--;
  660 + pathiterator.remove();
  661 + }
  662 + }
  663 + Iterator<Paint> paintiterator = paintLists.iterator();
  664 + while (paintiterator.hasNext()) {
  665 + Paint next = paintiterator.next();
  666 + if (next == paintLists.get(paintLists.size() - 1)) {
  667 + paintiterator.remove();
  668 + }
  669 + }
  670 + drawSurface();
  671 + }
  672 + }
  673 +
  674 +
  675 + public List<PointGroupEntity> getData() {
  676 + List<PointGroupEntity> pointXies = new ArrayList<>();
  677 + PointGroupEntity xy = new PointGroupEntity();
  678 + xy.w = 127.0f;
  679 + xy.h = 377.0f;
  680 + pointXies.add(xy);
  681 +
  682 + PointGroupEntity wh1 = new PointGroupEntity();
  683 + wh1.w = 145.40204f;
  684 + wh1.h = 386.0f;
  685 + pointXies.add(wh1);
  686 +
  687 + PointGroupEntity wh2 = new PointGroupEntity();
  688 + wh2.w = 148.0f;
  689 + wh2.h = 386.0f;
  690 + pointXies.add(wh2);
  691 +
  692 + PointGroupEntity wh3 = new PointGroupEntity();
  693 + wh3.w = 151.875f;
  694 + wh3.h = 386.0f;
  695 + pointXies.add(wh3);
  696 + PointGroupEntity wh4 = new PointGroupEntity();
  697 + wh4.w = 156.41933f;
  698 + wh4.h = 386.0f;
  699 + pointXies.add(wh4);
  700 +
  701 + PointGroupEntity wh5 = new PointGroupEntity();
  702 + wh5.w = 163.03827f;
  703 + wh5.h = 386.0f;
  704 + pointXies.add(wh5);
  705 + PointGroupEntity wh6 = new PointGroupEntity();
  706 + wh6.w = 171.26802f;
  707 + wh6.h = 378.28864f;
  708 + pointXies.add(wh6);
  709 +
  710 + PointGroupEntity wh7 = new PointGroupEntity();
  711 + wh7.w = 178.50021f;
  712 + wh7.h = 375.79993f;
  713 + pointXies.add(wh7);
  714 +
  715 + PointGroupEntity wh8 = new PointGroupEntity();
  716 + wh8.w = 186.9014f;
  717 + wh8.h = 374.51642f;
  718 + pointXies.add(wh8);
  719 +
  720 + PointGroupEntity wh9 = new PointGroupEntity();
  721 + wh9.w = 191.49982f;
  722 + wh9.h = 373.12506f;
  723 + pointXies.add(wh9);
  724 +
  725 + PointGroupEntity wh0 = new PointGroupEntity();
  726 + wh0.w = 194.86517f;
  727 + wh0.h = 372.04492f;
  728 + pointXies.add(wh0);
  729 + PointGroupEntity wh11 = new PointGroupEntity();
  730 + wh11.w = 197.6098f;
  731 + wh11.h = 372.0f;
  732 + pointXies.add(wh11);
  733 + return pointXies;
  734 + }
  735 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.chat;
  17 +
  18 +import android.os.Bundle;
  19 +import android.view.LayoutInflater;
  20 +import android.view.View;
  21 +import android.view.ViewGroup;
  22 +import android.widget.LinearLayout;
  23 +
  24 +
  25 +import com.mang.xdy.demo.R;
  26 +
  27 +import org.kymjs.kjframe.ui.SupportFragment;
  28 +
  29 +/**
  30 + * 聊天键盘功能界面
  31 + *
  32 + * @author kymjs (http://www.kymjs.com/) on 7/6/15.
  33 + */
  34 +public class ChatFunctionFragment extends SupportFragment {
  35 +
  36 + private LinearLayout layout1;
  37 + private LinearLayout layout2;
  38 +
  39 + private OnOperationListener listener;
  40 +
  41 + @Override
  42 + protected View inflaterView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
  43 + View view = View.inflate(getActivity(), R.layout.home_chat_item_menu, null);
  44 + return view;
  45 + }
  46 +
  47 + @Override
  48 + protected void initWidget(View parentView) {
  49 + super.initWidget(parentView);
  50 + layout1 = (LinearLayout) parentView.findViewById(R.id.chat_menu_images);
  51 + layout2 = (LinearLayout) parentView.findViewById(R.id.chat_menu_photo);
  52 +
  53 + layout1.setOnClickListener(this);
  54 + layout2.setOnClickListener(this);
  55 + }
  56 +
  57 + public void setOnOperationListener(OnOperationListener onOperationListener) {
  58 + this.listener = onOperationListener;
  59 + }
  60 +
  61 + @Override
  62 + protected void widgetClick(View v) {
  63 + super.widgetClick(v);
  64 + if (v == layout1) {
  65 + clickMenu(0);
  66 + } else if (v == layout2) {
  67 + clickMenu(1);
  68 + }
  69 + }
  70 +
  71 + private void clickMenu(int i) {
  72 + if (listener != null) {
  73 + listener.selectedFunction(i);
  74 + }
  75 + }
  76 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.chat;
  17 +
  18 +import android.app.Activity;
  19 +import android.graphics.Color;
  20 +import android.graphics.drawable.ColorDrawable;
  21 +import android.os.Bundle;
  22 +import android.support.v4.view.PagerAdapter;
  23 +import android.support.v4.view.ViewPager;
  24 +import android.support.v4.view.ViewPager.OnPageChangeListener;
  25 +import android.util.Log;
  26 +import android.view.Gravity;
  27 +import android.view.LayoutInflater;
  28 +import android.view.View;
  29 +import android.view.ViewGroup;
  30 +import android.widget.AdapterView;
  31 +import android.widget.AdapterView.OnItemClickListener;
  32 +import android.widget.FrameLayout.LayoutParams;
  33 +import android.widget.GridView;
  34 +import android.widget.LinearLayout;
  35 +import android.widget.RadioButton;
  36 +import android.widget.RadioGroup;
  37 +
  38 +
  39 +import com.mang.xdy.demo.R;
  40 +import com.mang.xdy.demo.adapter.FaceAdapter;
  41 +import com.mang.xdy.demo.bean.Faceicon;
  42 +
  43 +import org.kymjs.kjframe.ui.SupportFragment;
  44 +import org.kymjs.kjframe.utils.StringUtils;
  45 +
  46 +import java.io.File;
  47 +import java.util.ArrayList;
  48 +import java.util.List;
  49 +
  50 +/**
  51 + * 表情分类中每个分类的具体显示
  52 + *
  53 + * @author kymjs (http://www.kymjs.com/)
  54 + */
  55 +public class FacePageFragment extends SupportFragment {
  56 +
  57 + public static final String FACE_FOLDER_PATH = "face_folder_path";
  58 +
  59 + private static final int ITEM_PAGE_COUNT = 12;
  60 +
  61 + private ViewPager mPagerFace;
  62 + private LinearLayout pagePointLayout;
  63 +
  64 + private Activity aty;
  65 + private GridView[] allPageViews;
  66 + private RadioButton[] pointViews;
  67 + private OnOperationListener listener;
  68 +
  69 + //当前fragment(一个表情分类)所包含的全部表情
  70 + private List<Faceicon> datas;
  71 +
  72 + @Override
  73 + protected View inflaterView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
  74 + aty = getActivity();
  75 + View rootView = layoutInflater.inflate(R.layout.home_chat_frag_face, null);
  76 + return rootView;
  77 + }
  78 +
  79 + @Override
  80 + protected void initData() {
  81 + super.initData();
  82 + String folderPath = getArguments().getString(FACE_FOLDER_PATH);
  83 + if (StringUtils.isEmpty(folderPath)) {
  84 + folderPath = "";
  85 + Log.e("kymjs", getClass().getSimpleName() + " line 69, folder path is empty");
  86 + }
  87 + File folder = new File(folderPath);
  88 + if (folder.isDirectory()) {
  89 + File[] faceFiles = folder.listFiles();
  90 + datas = new ArrayList<>(faceFiles.length);
  91 + for (File faceFile : faceFiles) {
  92 + if (!faceFile.isHidden()) {
  93 + Faceicon data = new Faceicon();
  94 + data.setName("http://www.oschina.net/image/" + faceFile.getName());
  95 + data.setFileName(faceFile.getName());
  96 + data.setPath(faceFile.getAbsolutePath());
  97 + datas.add(data);
  98 + }
  99 + }
  100 + } else {
  101 + datas = new ArrayList<>(0);
  102 + }
  103 + }
  104 +
  105 + @Override
  106 + protected void initWidget(View rootView) {
  107 + super.initWidget(rootView);
  108 + mPagerFace = (ViewPager) rootView.findViewById(R.id.frag_pager_face);
  109 + pagePointLayout = (LinearLayout) rootView.findViewById(R.id.frag_point);
  110 +
  111 + int total = datas.size();
  112 + int pages = total / ITEM_PAGE_COUNT
  113 + + (total % ITEM_PAGE_COUNT == 0 ? 0 : 1);
  114 +
  115 + allPageViews = new GridView[pages];
  116 + pointViews = new RadioButton[pages];
  117 +
  118 + for (int x = 0; x < pages; x++) {
  119 + int start = x * ITEM_PAGE_COUNT;
  120 + int end = (start + ITEM_PAGE_COUNT) > total ? total
  121 + : (start + ITEM_PAGE_COUNT);
  122 + final List<Faceicon> itemDatas = datas.subList(start, end);
  123 + GridView view = new GridView(aty);
  124 + FaceAdapter faceAdapter = new FaceAdapter(view, itemDatas);
  125 + view.setAdapter(faceAdapter);
  126 +
  127 + view.setNumColumns(4);
  128 + view.setBackgroundColor(Color.TRANSPARENT);
  129 + view.setHorizontalSpacing(1);
  130 + view.setVerticalSpacing(1);
  131 + view.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
  132 + view.setCacheColorHint(0);
  133 + view.setVerticalScrollBarEnabled(false);
  134 + view.setPadding(5, 0, 5, 0);
  135 + view.setSelector(new ColorDrawable(Color.TRANSPARENT));
  136 + view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
  137 + LayoutParams.WRAP_CONTENT));
  138 + view.setGravity(Gravity.CENTER);
  139 +
  140 + view.setOnItemClickListener(new OnItemClickListener() {
  141 + @Override
  142 + public void onItemClick(AdapterView<?> parent, View view,
  143 + int position, long id) {
  144 + if (listener != null) {
  145 + listener.selectedFace(itemDatas.get(position));
  146 + }
  147 + }
  148 + });
  149 + allPageViews[x] = view;
  150 +
  151 + RadioButton tip = new RadioButton(aty);
  152 + tip.setBackgroundResource(R.drawable.home_selector_chat_emoji_btn);
  153 + RadioGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams(
  154 + 8, 8);
  155 + layoutParams.leftMargin = 10;
  156 + pagePointLayout.addView(tip, layoutParams);
  157 + if (x == 0) {
  158 + tip.setChecked(true);
  159 + }
  160 + pointViews[x] = tip;
  161 + }
  162 +
  163 + PagerAdapter facePagerAdapter = new FacePagerAdapter(allPageViews);
  164 + mPagerFace.setAdapter(facePagerAdapter);
  165 + mPagerFace.setOnPageChangeListener(new OnPageChangeListener() {
  166 +
  167 + @Override
  168 + public void onPageSelected(int index) {
  169 + pointViews[index].setChecked(true);
  170 + }
  171 +
  172 + @Override
  173 + public void onPageScrolled(int arg0, float arg1, int arg2) {
  174 + }
  175 +
  176 + @Override
  177 + public void onPageScrollStateChanged(int arg0) {
  178 + }
  179 + });
  180 + }
  181 +
  182 + public class FacePagerAdapter extends PagerAdapter {
  183 + private final GridView[] gridViewList;
  184 +
  185 + public FacePagerAdapter(GridView[] gridViewList) {
  186 + this.gridViewList = gridViewList;
  187 + }
  188 +
  189 + @Override
  190 + public int getCount() {
  191 + return gridViewList.length;
  192 + }
  193 +
  194 + @Override
  195 + public boolean isViewFromObject(View arg0, Object arg1) {
  196 + return arg0 == arg1;
  197 + }
  198 +
  199 + @Override
  200 + public int getItemPosition(Object object) {
  201 + return super.getItemPosition(object);
  202 + }
  203 +
  204 + @Override
  205 + public void destroyItem(View arg0, int arg1, Object arg2) {
  206 + ((ViewPager) arg0).removeView(gridViewList[arg1]);
  207 + }
  208 +
  209 + @Override
  210 + public Object instantiateItem(View arg0, int arg1) {
  211 + ((ViewPager) arg0).addView(gridViewList[arg1]);
  212 + return gridViewList[arg1];
  213 + }
  214 + }
  215 +
  216 + public void setOnOperationListener(OnOperationListener onOperationListener) {
  217 + this.listener = onOperationListener;
  218 + }
  219 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.chat;
  17 +
  18 +import android.app.Activity;
  19 +import android.content.Context;
  20 +import android.support.v4.app.FragmentActivity;
  21 +import android.support.v4.view.ViewPager;
  22 +import android.util.AttributeSet;
  23 +import android.view.View;
  24 +import android.view.inputmethod.InputMethodManager;
  25 +import android.widget.CheckBox;
  26 +import android.widget.EditText;
  27 +import android.widget.ImageView;
  28 +import android.widget.LinearLayout;
  29 +import android.widget.RelativeLayout;
  30 +
  31 +
  32 +import com.mang.xdy.demo.R;
  33 +import com.mang.xdy.demo.adapter.FaceCategroyAdapter;
  34 +
  35 +import java.util.List;
  36 +
  37 +/**
  38 + * 控件主界面
  39 + *
  40 + * @author kymjs (http://www.kymjs.com/)
  41 + */
  42 +public class KJChatKeyboard extends RelativeLayout implements
  43 + SoftKeyboardStateHelper.SoftKeyboardStateListener {
  44 +
  45 + private LinearLayout mToolsBoxCover;
  46 +
  47 + public interface OnToolBoxListener {
  48 + void onShowFace();
  49 + }
  50 +
  51 + public static final int LAYOUT_TYPE_HIDE = 0;
  52 + public static final int LAYOUT_TYPE_FACE = 1;
  53 + public static final int LAYOUT_TYPE_MORE = 2;
  54 +
  55 + /**
  56 + * 最上层输入框
  57 + */
  58 + private EditText mEtMsg;
  59 + private CheckBox mBtnFace;
  60 + private CheckBox mBtnMore;
  61 + private ImageView mBtnSend;
  62 +
  63 + /**
  64 + * 表情
  65 + */
  66 + private ViewPager mPagerFaceCagetory;
  67 + private RelativeLayout mRlFace;
  68 + private PagerSlidingTabStrip mFaceTabs;
  69 +
  70 + private int layoutType = LAYOUT_TYPE_HIDE;
  71 + private FaceCategroyAdapter adapter; //点击表情按钮时的适配器
  72 +
  73 + private List<String> mFaceData;
  74 +
  75 + private Context context;
  76 + private OnOperationListener listener;
  77 + private OnToolBoxListener mFaceListener;
  78 + private SoftKeyboardStateHelper mKeyboardHelper;
  79 +
  80 + public KJChatKeyboard(Context context) {
  81 + super(context);
  82 + init(context);
  83 + }
  84 +
  85 + public KJChatKeyboard(Context context, AttributeSet attrs) {
  86 + super(context, attrs);
  87 + init(context);
  88 + }
  89 +
  90 + public KJChatKeyboard(Context context, AttributeSet attrs, int defStyle) {
  91 + super(context, attrs, defStyle);
  92 + init(context);
  93 + }
  94 +
  95 + private void init(Context context) {
  96 + this.context = context;
  97 + View root = View.inflate(context, R.layout.home_chat_tool_box, null);
  98 + this.addView(root);
  99 + }
  100 +
  101 + @Override
  102 + protected void onFinishInflate() {
  103 + super.onFinishInflate();
  104 + initData();
  105 + this.initWidget();
  106 + }
  107 +
  108 + private void initData() {
  109 + mKeyboardHelper = new SoftKeyboardStateHelper(((Activity) getContext())
  110 + .getWindow().getDecorView());
  111 + mKeyboardHelper.addSoftKeyboardStateListener(this);
  112 + }
  113 +
  114 + private void initWidget() {
  115 + mEtMsg = (EditText) findViewById(R.id.toolbox_et_message);
  116 + mBtnSend = (ImageView) findViewById(R.id.toolbox_btn_send);
  117 + mBtnFace = (CheckBox) findViewById(R.id.toolbox_btn_face);
  118 + mBtnMore = (CheckBox) findViewById(R.id.toolbox_btn_more);
  119 + mRlFace = (RelativeLayout) findViewById(R.id.toolbox_layout_face);
  120 + mPagerFaceCagetory = (ViewPager) findViewById(R.id.toolbox_pagers_face);
  121 + mFaceTabs = (PagerSlidingTabStrip) findViewById(R.id.toolbox_tabs);
  122 + mToolsBoxCover = (LinearLayout) findViewById(R.id.ll_cover);
  123 + adapter = new FaceCategroyAdapter(((FragmentActivity) getContext())
  124 + .getSupportFragmentManager(), LAYOUT_TYPE_FACE);
  125 + mBtnSend.setOnClickListener(new OnClickListener() {
  126 + @Override
  127 + public void onClick(View v) {
  128 + if (listener != null) {
  129 + String content = mEtMsg.getText().toString();
  130 + listener.send(content);
  131 + mEtMsg.setText(null);
  132 + }
  133 + }
  134 + });
  135 + // 点击表情按钮
  136 + mBtnFace.setOnClickListener(getFunctionBtnListener(LAYOUT_TYPE_FACE));
  137 + // 点击表情按钮旁边的加号
  138 + mBtnMore.setOnClickListener(getFunctionBtnListener(LAYOUT_TYPE_MORE));
  139 + // 点击消息输入框
  140 + mEtMsg.setOnClickListener(new OnClickListener() {
  141 + @Override
  142 + public void onClick(View v) {
  143 + hideLayout();
  144 + }
  145 + });
  146 + }
  147 +
  148 + /*************************
  149 + * 内部方法 start
  150 + ************************/
  151 +
  152 + private OnClickListener getFunctionBtnListener(final int which) {
  153 + return new OnClickListener() {
  154 + @Override
  155 + public void onClick(View v) {
  156 + setEditTextFocus();
  157 + if (isShow() && which == layoutType) {
  158 + hideLayout();
  159 + showKeyboard(context);
  160 + } else {
  161 + changeLayout(which);
  162 + showLayout();
  163 + mBtnFace.setChecked(layoutType == LAYOUT_TYPE_FACE);
  164 + mBtnMore.setChecked(layoutType == LAYOUT_TYPE_MORE);
  165 + }
  166 + }
  167 + };
  168 + }
  169 +
  170 + public void setEditTextFocus(){
  171 + if (mEtMsg!=null){
  172 + mEtMsg.setFocusable(true);
  173 + mEtMsg.setFocusableInTouchMode(true);
  174 + mEtMsg.requestFocus();
  175 + mEtMsg.findFocus();
  176 + mEtMsg.invalidate();
  177 + }
  178 +
  179 + }
  180 +
  181 + private void changeLayout(int mode) {
  182 + adapter = new FaceCategroyAdapter(((FragmentActivity) getContext())
  183 + .getSupportFragmentManager(), mode);
  184 + adapter.setOnOperationListener(listener);
  185 + layoutType = mode;
  186 + setFaceData(mFaceData);
  187 + }
  188 +
  189 + @Override
  190 + public void onSoftKeyboardOpened(int keyboardHeightInPx) {
  191 + hideLayout();
  192 + }
  193 +
  194 + @Override
  195 + public void onSoftKeyboardClosed() {
  196 + }
  197 +
  198 + /***************************** 内部方法 end ******************************/
  199 +
  200 + /**************************
  201 + * 可选调用的方法 start
  202 + **************************/
  203 +
  204 + public void setFaceData(List<String> faceData) {
  205 + mFaceData = faceData;
  206 + adapter.refresh(faceData);
  207 + mPagerFaceCagetory.setAdapter(adapter);
  208 + mFaceTabs.setViewPager(mPagerFaceCagetory);
  209 + if (layoutType == LAYOUT_TYPE_MORE) {
  210 + mFaceTabs.setVisibility(GONE);
  211 + } else {
  212 + //加1是表示第一个分类为默认的emoji表情分类,这个分类是固定不可更改的
  213 + if (faceData.size() + 1 < 2) {
  214 + mFaceTabs.setVisibility(GONE);
  215 + } else {
  216 + mFaceTabs.setVisibility(VISIBLE);
  217 + }
  218 + }
  219 + }
  220 +
  221 + public EditText getEditTextBox() {
  222 + return mEtMsg;
  223 + }
  224 +
  225 + public void showLayout() {
  226 + hideKeyboard(this.context);
  227 + // 延迟一会,让键盘先隐藏再显示表情键盘,否则会有一瞬间表情键盘和软键盘同时显示
  228 +
  229 +
  230 + postDelayed(new Runnable() {
  231 + @Override
  232 + public void run() {
  233 + mRlFace.setVisibility(View.VISIBLE);
  234 + if (mFaceListener != null) {
  235 + mFaceListener.onShowFace();
  236 + }
  237 + }
  238 + }, 50);
  239 + }
  240 +
  241 +
  242 + public boolean isShow() {
  243 + return mRlFace.getVisibility() == VISIBLE;
  244 + }
  245 +
  246 + public void hideLayout() {
  247 + mRlFace.setVisibility(View.GONE);
  248 + if (mBtnFace.isChecked()) {
  249 + mBtnFace.setChecked(false);
  250 + }
  251 + if (mBtnMore.isChecked()) {
  252 + mBtnMore.setChecked(false);
  253 + }
  254 + }
  255 +
  256 + /**
  257 + * 隐藏软键盘
  258 + */
  259 + public void hideKeyboard(Context context) {
  260 + Activity activity = (Activity) context;
  261 + if (activity != null) {
  262 + InputMethodManager imm = (InputMethodManager) activity
  263 + .getSystemService(Context.INPUT_METHOD_SERVICE);
  264 + if (imm.isActive() && activity.getCurrentFocus() != null) {
  265 + imm.hideSoftInputFromWindow(activity.getCurrentFocus()
  266 + .getWindowToken(), 0);
  267 + }
  268 + }
  269 + }
  270 +
  271 + /**
  272 + * 显示软键盘
  273 + */
  274 + public static void showKeyboard(Context context) {
  275 + Activity activity = (Activity) context;
  276 + if (activity != null) {
  277 + InputMethodManager imm = (InputMethodManager) activity
  278 + .getSystemService(Context.INPUT_METHOD_SERVICE);
  279 + imm.showSoftInputFromInputMethod(activity.getCurrentFocus()
  280 + .getWindowToken(), 0);
  281 + imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
  282 + }
  283 +
  284 +
  285 + }
  286 +
  287 +
  288 + public OnOperationListener getOnOperationListener() {
  289 + return listener;
  290 + }
  291 +
  292 + public void setOnOperationListener(OnOperationListener onOperationListener) {
  293 + this.listener = onOperationListener;
  294 + adapter.setOnOperationListener(onOperationListener);
  295 + }
  296 +
  297 + public void setOnToolBoxListener(OnToolBoxListener mFaceListener) {
  298 + this.mFaceListener = mFaceListener;
  299 + }
  300 +
  301 + public void setToolBoxIsClick(boolean b){
  302 + if (b){
  303 + if (isShow()){
  304 + hideLayout();
  305 + }
  306 + mToolsBoxCover.setVisibility(View.VISIBLE);
  307 + mToolsBoxCover.setOnClickListener(null);
  308 + }else {
  309 + mToolsBoxCover.setVisibility(View.GONE);
  310 + }
  311 + }
  312 +
  313 + /*********************** 可选调用的方法 end ******************************/
  314 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.chat;
  17 +
  18 +
  19 +import com.mang.xdy.demo.bean.Faceicon;
  20 +
  21 +/**
  22 + * 表情栏顶部按钮的监听器
  23 + *
  24 + * @author kymjs (http://www.kymjs.com/)
  25 + */
  26 +public interface OnOperationListener {
  27 +
  28 + void send(String content);
  29 +
  30 + void selectedFace(Faceicon content);
  31 +
  32 + void selectedEmoji(String content);
  33 +
  34 + void selectedBackSpace(String back);
  35 +
  36 + void selectedFunction(int index);
  37 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.chat;
  17 +
  18 +import android.annotation.SuppressLint;
  19 +import android.content.Context;
  20 +import android.content.res.TypedArray;
  21 +import android.graphics.Canvas;
  22 +import android.graphics.Paint;
  23 +import android.graphics.Paint.Style;
  24 +import android.graphics.Typeface;
  25 +import android.os.Build;
  26 +import android.os.Parcel;
  27 +import android.os.Parcelable;
  28 +import android.support.v4.view.ViewPager;
  29 +import android.support.v4.view.ViewPager.OnPageChangeListener;
  30 +import android.util.AttributeSet;
  31 +import android.util.DisplayMetrics;
  32 +import android.util.TypedValue;
  33 +import android.view.Gravity;
  34 +import android.view.View;
  35 +import android.view.ViewTreeObserver.OnGlobalLayoutListener;
  36 +import android.widget.HorizontalScrollView;
  37 +import android.widget.ImageView;
  38 +import android.widget.LinearLayout;
  39 +import android.widget.TextView;
  40 +
  41 +
  42 +import com.mang.xdy.demo.R;
  43 +
  44 +import java.util.Locale;
  45 +
  46 +/**
  47 + * 表情栏底部表情分类
  48 + *
  49 + * @author kymjs (http://www.kymjs.com/)
  50 + */
  51 +public class PagerSlidingTabStrip extends HorizontalScrollView {
  52 +
  53 + public interface IconTabProvider {
  54 + void setPageIcon(int position, ImageView image);
  55 + }
  56 +
  57 + // @formatter:off
  58 + private static final int[] ATTRS = new int[]{android.R.attr.textSize,
  59 + android.R.attr.textColor};
  60 + // @formatter:on
  61 +
  62 + private final LinearLayout.LayoutParams defaultTabLayoutParams;
  63 + private final LinearLayout.LayoutParams expandedTabLayoutParams;
  64 +
  65 + private final PageListener pageListener = new PageListener();
  66 + public OnPageChangeListener delegatePageListener;
  67 +
  68 + private final LinearLayout tabsContainer;
  69 + private ViewPager pager;
  70 +
  71 + private int tabCount;
  72 +
  73 + private int currentPosition = 0;
  74 + private float currentPositionOffset = 0f;
  75 +
  76 + private final Paint rectPaint;
  77 + private final Paint dividerPaint;
  78 +
  79 + private int indicatorColor = 0xFF666666;
  80 + private int underlineColor = 0x1A000000;
  81 + private int dividerColor = 0x1A000000;
  82 +
  83 + private boolean shouldExpand = false;
  84 + private boolean textAllCaps = true;
  85 +
  86 + private int scrollOffset = 52;
  87 + private int indicatorHeight = 8;
  88 + private int underlineHeight = 2;
  89 + private int dividerPadding = 12;
  90 + private int tabPadding = 24;
  91 + private int dividerWidth = 1;
  92 +
  93 + private int tabTextSize = 12;
  94 + private int tabTextColor = 0xFF666666;
  95 + private Typeface tabTypeface = null;
  96 + private int tabTypefaceStyle = Typeface.BOLD;
  97 +
  98 + private int lastScrollX = 0;
  99 +
  100 + private int tabBackgroundResId = R.drawable.home_selector_tab_bg;
  101 +
  102 + private Locale locale;
  103 +
  104 + public PagerSlidingTabStrip(Context context) {
  105 + this(context, null);
  106 + }
  107 +
  108 + public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
  109 + this(context, attrs, 0);
  110 + }
  111 +
  112 + public PagerSlidingTabStrip(Context context, AttributeSet attrs,
  113 + int defStyle) {
  114 + super(context, attrs, defStyle);
  115 +
  116 + setFillViewport(true);
  117 + setWillNotDraw(false);
  118 +
  119 + tabsContainer = new LinearLayout(context);
  120 + tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
  121 + tabsContainer.setLayoutParams(new LayoutParams(
  122 + LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  123 + addView(tabsContainer);
  124 +
  125 + DisplayMetrics dm = getResources().getDisplayMetrics();
  126 +
  127 + scrollOffset = (int) TypedValue.applyDimension(
  128 + TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
  129 + indicatorHeight = (int) TypedValue.applyDimension(
  130 + TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
  131 + underlineHeight = (int) TypedValue.applyDimension(
  132 + TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
  133 + dividerPadding = (int) TypedValue.applyDimension(
  134 + TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
  135 + tabPadding = (int) TypedValue.applyDimension(
  136 + TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
  137 + dividerWidth = (int) TypedValue.applyDimension(
  138 + TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
  139 + tabTextSize = (int) TypedValue.applyDimension(
  140 + TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
  141 +
  142 + // get system attrs (android:textSize and android:textColor)
  143 +
  144 + TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
  145 +
  146 + tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
  147 + tabTextColor = a.getColor(1, tabTextColor);
  148 +
  149 + a.recycle();
  150 +
  151 + // get custom attrs
  152 +
  153 + a = context.obtainStyledAttributes(attrs,
  154 + R.styleable.home_PagerSlidingTabStrip);
  155 +
  156 + indicatorColor = a.getColor(
  157 + R.styleable.home_PagerSlidingTabStrip_home_pstsIndicatorColor,
  158 + indicatorColor);
  159 + underlineColor = a.getColor(
  160 + R.styleable.home_PagerSlidingTabStrip_home_pstsUnderlineColor,
  161 + underlineColor);
  162 + dividerColor = a
  163 + .getColor(R.styleable.home_PagerSlidingTabStrip_home_pstsDividerColor,
  164 + dividerColor);
  165 + indicatorHeight = a.getDimensionPixelSize(
  166 + R.styleable.home_PagerSlidingTabStrip_home_pstsIndicatorHeight,
  167 + indicatorHeight);
  168 + underlineHeight = a.getDimensionPixelSize(
  169 + R.styleable.home_PagerSlidingTabStrip_home_pstsUnderlineHeight,
  170 + underlineHeight);
  171 + dividerPadding = a.getDimensionPixelSize(
  172 + R.styleable.home_PagerSlidingTabStrip_home_pstsDividerPadding,
  173 + dividerPadding);
  174 + tabPadding = a.getDimensionPixelSize(
  175 + R.styleable.home_PagerSlidingTabStrip_home_pstsTabPaddingLeftRight,
  176 + tabPadding);
  177 + tabBackgroundResId = a.getResourceId(
  178 + R.styleable.home_PagerSlidingTabStrip_home_pstsTabBackground,
  179 + tabBackgroundResId);
  180 + shouldExpand = a
  181 + .getBoolean(R.styleable.home_PagerSlidingTabStrip_home_pstsShouldExpand,
  182 + shouldExpand);
  183 + scrollOffset = a
  184 + .getDimensionPixelSize(
  185 + R.styleable.home_PagerSlidingTabStrip_home_pstsScrollOffset,
  186 + scrollOffset);
  187 + textAllCaps = a.getBoolean(
  188 + R.styleable.home_PagerSlidingTabStrip_home_pstsTextAllCaps, textAllCaps);
  189 +
  190 + a.recycle();
  191 +
  192 + rectPaint = new Paint();
  193 + rectPaint.setAntiAlias(true);
  194 + rectPaint.setStyle(Style.FILL);
  195 +
  196 + dividerPaint = new Paint();
  197 + dividerPaint.setAntiAlias(true);
  198 + dividerPaint.setStrokeWidth(dividerWidth);
  199 +
  200 + defaultTabLayoutParams = new LinearLayout.LayoutParams(
  201 + LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
  202 + expandedTabLayoutParams = new LinearLayout.LayoutParams(0,
  203 + LayoutParams.MATCH_PARENT, 1.0f);
  204 +
  205 + if (locale == null) {
  206 + locale = getResources().getConfiguration().locale;
  207 + }
  208 + }
  209 +
  210 + public void setViewPager(ViewPager pager) {
  211 + this.pager = pager;
  212 +
  213 + if (pager.getAdapter() == null) {
  214 + throw new IllegalStateException(
  215 + "ViewPager does not have adapter instance.");
  216 + }
  217 +
  218 + pager.setOnPageChangeListener(pageListener);
  219 +
  220 + notifyDataSetChanged();
  221 + }
  222 +
  223 + public void setOnPageChangeListener(OnPageChangeListener listener) {
  224 + this.delegatePageListener = listener;
  225 + }
  226 +
  227 + public void notifyDataSetChanged() {
  228 +
  229 + tabsContainer.removeAllViews();
  230 +
  231 + tabCount = pager.getAdapter().getCount();
  232 +
  233 + for (int i = 0; i < tabCount; i++) {
  234 + if (pager.getAdapter() instanceof IconTabProvider) {
  235 + ImageView image = new ImageView(getContext());
  236 + ((IconTabProvider) pager.getAdapter()).setPageIcon(i, image);
  237 + addTab(i, image);
  238 + } else {
  239 + addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
  240 + }
  241 + }
  242 +
  243 + updateTabStyles();
  244 +
  245 + getViewTreeObserver().addOnGlobalLayoutListener(
  246 + new OnGlobalLayoutListener() {
  247 +
  248 + @SuppressWarnings("deprecation")
  249 + @SuppressLint("NewApi")
  250 + @Override
  251 + public void onGlobalLayout() {
  252 +
  253 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
  254 + getViewTreeObserver().removeGlobalOnLayoutListener(
  255 + this);
  256 + } else {
  257 + getViewTreeObserver().removeOnGlobalLayoutListener(
  258 + this);
  259 + }
  260 +
  261 + currentPosition = pager.getCurrentItem();
  262 + scrollToChild(currentPosition, 0);
  263 + }
  264 + });
  265 +
  266 + }
  267 +
  268 + private void addTextTab(final int position, String title) {
  269 +
  270 + TextView tab = new TextView(getContext());
  271 + tab.setText(title);
  272 + tab.setGravity(Gravity.CENTER);
  273 + tab.setSingleLine();
  274 +
  275 + addTab(position, tab);
  276 + }
  277 +
  278 + private void addTab(final int position, View tab) {
  279 + tab.setFocusable(true);
  280 + tab.setOnClickListener(new OnClickListener() {
  281 + @Override
  282 + public void onClick(View v) {
  283 + pager.setCurrentItem(position);
  284 + }
  285 + });
  286 +
  287 + tab.setPadding(tabPadding, 0, tabPadding, 0);
  288 + tabsContainer
  289 + .addView(tab, position, shouldExpand ? expandedTabLayoutParams
  290 + : defaultTabLayoutParams);
  291 + }
  292 +
  293 + private void updateTabStyles() {
  294 +
  295 + for (int i = 0; i < tabCount; i++) {
  296 +
  297 + View v = tabsContainer.getChildAt(i);
  298 +
  299 + v.setBackgroundResource(tabBackgroundResId);
  300 +
  301 + if (v instanceof TextView) {
  302 +
  303 + TextView tab = (TextView) v;
  304 + tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
  305 + tab.setTypeface(tabTypeface, tabTypefaceStyle);
  306 + tab.setTextColor(tabTextColor);
  307 +
  308 + // setAllCaps() is only available from API 14, so the upper case
  309 + // is made manually if we are on a
  310 + // pre-ICS-build
  311 + if (textAllCaps) {
  312 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
  313 + tab.setAllCaps(true);
  314 + } else {
  315 + tab.setText(tab.getText().toString()
  316 + .toUpperCase(locale));
  317 + }
  318 + }
  319 + }
  320 + }
  321 +
  322 + }
  323 +
  324 + private void scrollToChild(int position, int offset) {
  325 +
  326 + if (tabCount == 0) {
  327 + return;
  328 + }
  329 +
  330 + int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
  331 +
  332 + if (position > 0 || offset > 0) {
  333 + newScrollX -= scrollOffset;
  334 + }
  335 +
  336 + if (newScrollX != lastScrollX) {
  337 + lastScrollX = newScrollX;
  338 + scrollTo(newScrollX, 0);
  339 + }
  340 +
  341 + }
  342 +
  343 + @Override
  344 + protected void onDraw(Canvas canvas) {
  345 + super.onDraw(canvas);
  346 +
  347 + if (isInEditMode() || tabCount == 0) {
  348 + return;
  349 + }
  350 +
  351 + final int height = getHeight();
  352 +
  353 + // draw indicator line
  354 +
  355 + rectPaint.setColor(indicatorColor);
  356 +
  357 + // default: line below current tab
  358 + View currentTab = tabsContainer.getChildAt(currentPosition);
  359 + float lineLeft = currentTab.getLeft();
  360 + float lineRight = currentTab.getRight();
  361 +
  362 + // if there is an offset, start interpolating left and right coordinates
  363 + // between current and next tab
  364 + if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
  365 +
  366 + View nextTab = tabsContainer.getChildAt(currentPosition + 1);
  367 + final float nextTabLeft = nextTab.getLeft();
  368 + final float nextTabRight = nextTab.getRight();
  369 +
  370 + lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset)
  371 + * lineLeft);
  372 + lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset)
  373 + * lineRight);
  374 + }
  375 +
  376 + canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height,
  377 + rectPaint);
  378 +
  379 + // draw underline
  380 +
  381 + rectPaint.setColor(underlineColor);
  382 + canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(),
  383 + height, rectPaint);
  384 +
  385 + // draw divider
  386 +
  387 + dividerPaint.setColor(dividerColor);
  388 + for (int i = 0; i < tabCount - 1; i++) {
  389 + View tab = tabsContainer.getChildAt(i);
  390 + canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(),
  391 + height - dividerPadding, dividerPaint);
  392 + }
  393 + }
  394 +
  395 + private class PageListener implements OnPageChangeListener {
  396 +
  397 + @Override
  398 + public void onPageScrolled(int position, float positionOffset,
  399 + int positionOffsetPixels) {
  400 +
  401 + currentPosition = position;
  402 + currentPositionOffset = positionOffset;
  403 +
  404 + scrollToChild(position, (int) (positionOffset * tabsContainer
  405 + .getChildAt(position).getWidth()));
  406 +
  407 + invalidate();
  408 +
  409 + if (delegatePageListener != null) {
  410 + delegatePageListener.onPageScrolled(position, positionOffset,
  411 + positionOffsetPixels);
  412 + }
  413 + }
  414 +
  415 + @Override
  416 + public void onPageScrollStateChanged(int state) {
  417 + if (state == ViewPager.SCROLL_STATE_IDLE) {
  418 + scrollToChild(pager.getCurrentItem(), 0);
  419 + }
  420 +
  421 + if (delegatePageListener != null) {
  422 + delegatePageListener.onPageScrollStateChanged(state);
  423 + }
  424 + }
  425 +
  426 + @Override
  427 + public void onPageSelected(int position) {
  428 + if (delegatePageListener != null) {
  429 + delegatePageListener.onPageSelected(position);
  430 + }
  431 + }
  432 +
  433 + }
  434 +
  435 + public void setIndicatorColor(int indicatorColor) {
  436 + this.indicatorColor = indicatorColor;
  437 + invalidate();
  438 + }
  439 +
  440 + public void setIndicatorColorResource(int resId) {
  441 + this.indicatorColor = getResources().getColor(resId);
  442 + invalidate();
  443 + }
  444 +
  445 + public int getIndicatorColor() {
  446 + return this.indicatorColor;
  447 + }
  448 +
  449 + public void setIndicatorHeight(int indicatorLineHeightPx) {
  450 + this.indicatorHeight = indicatorLineHeightPx;
  451 + invalidate();
  452 + }
  453 +
  454 + public int getIndicatorHeight() {
  455 + return indicatorHeight;
  456 + }
  457 +
  458 + public void setUnderlineColor(int underlineColor) {
  459 + this.underlineColor = underlineColor;
  460 + invalidate();
  461 + }
  462 +
  463 + public void setUnderlineColorResource(int resId) {
  464 + this.underlineColor = getResources().getColor(resId);
  465 + invalidate();
  466 + }
  467 +
  468 + public int getUnderlineColor() {
  469 + return underlineColor;
  470 + }
  471 +
  472 + public void setDividerColor(int dividerColor) {
  473 + this.dividerColor = dividerColor;
  474 + invalidate();
  475 + }
  476 +
  477 + public void setDividerColorResource(int resId) {
  478 + this.dividerColor = getResources().getColor(resId);
  479 + invalidate();
  480 + }
  481 +
  482 + public int getDividerColor() {
  483 + return dividerColor;
  484 + }
  485 +
  486 + public void setUnderlineHeight(int underlineHeightPx) {
  487 + this.underlineHeight = underlineHeightPx;
  488 + invalidate();
  489 + }
  490 +
  491 + public int getUnderlineHeight() {
  492 + return underlineHeight;
  493 + }
  494 +
  495 + public void setDividerPadding(int dividerPaddingPx) {
  496 + this.dividerPadding = dividerPaddingPx;
  497 + invalidate();
  498 + }
  499 +
  500 + public int getDividerPadding() {
  501 + return dividerPadding;
  502 + }
  503 +
  504 + public void setScrollOffset(int scrollOffsetPx) {
  505 + this.scrollOffset = scrollOffsetPx;
  506 + invalidate();
  507 + }
  508 +
  509 + public int getScrollOffset() {
  510 + return scrollOffset;
  511 + }
  512 +
  513 + public void setShouldExpand(boolean shouldExpand) {
  514 + this.shouldExpand = shouldExpand;
  515 + requestLayout();
  516 + }
  517 +
  518 + public boolean getShouldExpand() {
  519 + return shouldExpand;
  520 + }
  521 +
  522 + public boolean isTextAllCaps() {
  523 + return textAllCaps;
  524 + }
  525 +
  526 + public void setAllCaps(boolean textAllCaps) {
  527 + this.textAllCaps = textAllCaps;
  528 + }
  529 +
  530 + public void setTextSize(int textSizePx) {
  531 + this.tabTextSize = textSizePx;
  532 + updateTabStyles();
  533 + }
  534 +
  535 + public int getTextSize() {
  536 + return tabTextSize;
  537 + }
  538 +
  539 + public void setTextColor(int textColor) {
  540 + this.tabTextColor = textColor;
  541 + updateTabStyles();
  542 + }
  543 +
  544 + public void setTextColorResource(int resId) {
  545 + this.tabTextColor = getResources().getColor(resId);
  546 + updateTabStyles();
  547 + }
  548 +
  549 + public int getTextColor() {
  550 + return tabTextColor;
  551 + }
  552 +
  553 + public void setTypeface(Typeface typeface, int style) {
  554 + this.tabTypeface = typeface;
  555 + this.tabTypefaceStyle = style;
  556 + updateTabStyles();
  557 + }
  558 +
  559 + public void setTabBackground(int resId) {
  560 + this.tabBackgroundResId = resId;
  561 + }
  562 +
  563 + public int getTabBackground() {
  564 + return tabBackgroundResId;
  565 + }
  566 +
  567 + public void setTabPaddingLeftRight(int paddingPx) {
  568 + this.tabPadding = paddingPx;
  569 + updateTabStyles();
  570 + }
  571 +
  572 + public int getTabPaddingLeftRight() {
  573 + return tabPadding;
  574 + }
  575 +
  576 + @Override
  577 + public void onRestoreInstanceState(Parcelable state) {
  578 + SavedState savedState = (SavedState) state;
  579 + super.onRestoreInstanceState(savedState.getSuperState());
  580 + currentPosition = savedState.currentPosition;
  581 + requestLayout();
  582 + }
  583 +
  584 + @Override
  585 + public Parcelable onSaveInstanceState() {
  586 + Parcelable superState = super.onSaveInstanceState();
  587 + SavedState savedState = new SavedState(superState);
  588 + savedState.currentPosition = currentPosition;
  589 + return savedState;
  590 + }
  591 +
  592 + static class SavedState extends BaseSavedState {
  593 + int currentPosition;
  594 +
  595 + public SavedState(Parcelable superState) {
  596 + super(superState);
  597 + }
  598 +
  599 + private SavedState(Parcel in) {
  600 + super(in);
  601 + currentPosition = in.readInt();
  602 + }
  603 +
  604 + @Override
  605 + public void writeToParcel(Parcel dest, int flags) {
  606 + super.writeToParcel(dest, flags);
  607 + dest.writeInt(currentPosition);
  608 + }
  609 +
  610 + public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
  611 + @Override
  612 + public SavedState createFromParcel(Parcel in) {
  613 + return new SavedState(in);
  614 + }
  615 +
  616 + @Override
  617 + public SavedState[] newArray(int size) {
  618 + return new SavedState[size];
  619 + }
  620 + };
  621 + }
  622 +
  623 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.chat;
  17 +
  18 +import android.graphics.Rect;
  19 +import android.view.View;
  20 +import android.view.ViewTreeObserver;
  21 +
  22 +import java.util.LinkedList;
  23 +import java.util.List;
  24 +
  25 +/**
  26 + * 软键盘监听器助手
  27 + *
  28 + * @author kymjs (http://www.kymjs.com)
  29 + */
  30 +public class SoftKeyboardStateHelper implements
  31 + ViewTreeObserver.OnGlobalLayoutListener {
  32 +
  33 + public interface SoftKeyboardStateListener {
  34 + void onSoftKeyboardOpened(int keyboardHeightInPx);
  35 +
  36 + void onSoftKeyboardClosed();
  37 + }
  38 +
  39 + private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
  40 + private final View activityRootView;
  41 + private int lastSoftKeyboardHeightInPx;
  42 + private boolean isSoftKeyboardOpened;
  43 +
  44 + public SoftKeyboardStateHelper(View activityRootView) {
  45 + this(activityRootView, false);
  46 + }
  47 +
  48 + public SoftKeyboardStateHelper(View activityRootView,
  49 + boolean isSoftKeyboardOpened) {
  50 + this.activityRootView = activityRootView;
  51 + this.isSoftKeyboardOpened = isSoftKeyboardOpened;
  52 + activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
  53 + }
  54 +
  55 + @Override
  56 + public void onGlobalLayout() {
  57 + final Rect r = new Rect();
  58 + // r will be populated with the coordinates of your view that area still
  59 + // visible.
  60 + activityRootView.getWindowVisibleDisplayFrame(r);
  61 +
  62 + final int heightDiff = activityRootView.getRootView().getHeight()
  63 + - (r.bottom - r.top);
  64 + if (!isSoftKeyboardOpened && heightDiff > 100) { // if more than 100
  65 + // pixels, its probably
  66 + // a keyboard...
  67 + isSoftKeyboardOpened = true;
  68 + notifyOnSoftKeyboardOpened(heightDiff);
  69 + } else if (isSoftKeyboardOpened && heightDiff < 100) {
  70 + isSoftKeyboardOpened = false;
  71 + notifyOnSoftKeyboardClosed();
  72 + }
  73 + }
  74 +
  75 + public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
  76 + this.isSoftKeyboardOpened = isSoftKeyboardOpened;
  77 + }
  78 +
  79 + public boolean isSoftKeyboardOpened() {
  80 + return isSoftKeyboardOpened;
  81 + }
  82 +
  83 + /**
  84 + * Default value is zero (0)
  85 + *
  86 + * @return last saved keyboard height in px
  87 + */
  88 + public int getLastSoftKeyboardHeightInPx() {
  89 + return lastSoftKeyboardHeightInPx;
  90 + }
  91 +
  92 + public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
  93 + listeners.add(listener);
  94 + }
  95 +
  96 + public void removeSoftKeyboardStateListener(
  97 + SoftKeyboardStateListener listener) {
  98 + listeners.remove(listener);
  99 + }
  100 +
  101 + private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
  102 + this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;
  103 +
  104 + for (SoftKeyboardStateListener listener : listeners) {
  105 + if (listener != null) {
  106 + listener.onSoftKeyboardOpened(keyboardHeightInPx);
  107 + }
  108 + }
  109 + }
  110 +
  111 + private void notifyOnSoftKeyboardClosed() {
  112 + for (SoftKeyboardStateListener listener : listeners) {
  113 + if (listener != null) {
  114 + listener.onSoftKeyboardClosed();
  115 + }
  116 + }
  117 + }
  118 +}
  1 +package com.mang.xdy.demo.widget.chat;
  2 +
  3 +import android.content.Context;
  4 +import android.content.Intent;
  5 +import android.graphics.Color;
  6 +import android.net.Uri;
  7 +import android.provider.Browser;
  8 +import android.text.Html;
  9 +import android.text.SpannableStringBuilder;
  10 +import android.text.Spanned;
  11 +import android.text.TextPaint;
  12 +import android.text.method.LinkMovementMethod;
  13 +import android.text.style.ClickableSpan;
  14 +import android.text.style.URLSpan;
  15 +import android.view.View;
  16 +import android.widget.TextView;
  17 +
  18 +import java.util.regex.Matcher;
  19 +import java.util.regex.Pattern;
  20 +
  21 +/**
  22 + * 各种链接跳转样式
  23 + *
  24 + * @author kymjs (http://www.kymjs.com/) on 8/10/15.
  25 + */
  26 +public class UrlUtils {
  27 +
  28 +
  29 + /**
  30 + * 让TextView自动解析URL并高亮设置点击链接(链接不支持中文)
  31 + * Note:深深的体会到,写一个正则不容易啊,Android居然还不支持POSIX字符
  32 + * <p/>
  33 + * Created by kymjs(www.kymjs.com) on 8/5/15.
  34 + *
  35 + * @param tv TextView
  36 + * @param content 要高亮的内容
  37 + * @return 已经解析之后的TextView
  38 + */
  39 + public static TextView handleText(TextView tv, String content) {
  40 + SpannableStringBuilder sp = new SpannableStringBuilder(content);
  41 + //又碰上一个坑,在Android中的\p{Alnum}和Java中的\p{Alnum}不是同一个值,非得要我换成[a-zA-Z0-9]才行
  42 + Pattern pattern = Pattern.compile("(http|https|ftp|svn)://([a-zA-Z0-9]+[/?.?])" +
  43 + "+[a-zA-Z0-9]*\\??([a-zA-Z0-9]*=[a-zA-Z0-9]*&?)*");
  44 + Matcher matcher = pattern.matcher(content);
  45 +
  46 + while (matcher.find()) {
  47 + String url = matcher.group();
  48 + int start = content.indexOf(url);
  49 + if (start >= 0) {
  50 + int end = start + url.length();
  51 + sp.setSpan(new URLSpan(url), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  52 + sp.setSpan(getClickableSpan(url), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  53 + }
  54 + }
  55 + tv.setText(sp);
  56 + tv.setMovementMethod(LinkMovementMethod.getInstance());
  57 + return tv;
  58 + }
  59 +
  60 + /**
  61 + * 处理html数据的高亮与响应
  62 + *
  63 + * @param tv
  64 + * @param content
  65 + * @return
  66 + */
  67 + public static TextView handleHtmlText(TextView tv, String content) {
  68 + SpannableStringBuilder sp = new SpannableStringBuilder(Html.fromHtml(content));
  69 + URLSpan[] urlSpans = sp.getSpans(0, sp.length(), URLSpan.class);
  70 + for (final URLSpan span : urlSpans) {
  71 + int start = sp.getSpanStart(span);
  72 + int end = sp.getSpanEnd(span);
  73 + sp.setSpan(getClickableSpan(span.getURL()), start, end, Spanned
  74 + .SPAN_EXCLUSIVE_EXCLUSIVE);
  75 + }
  76 + tv.setText(sp);
  77 + tv.setMovementMethod(LinkMovementMethod.getInstance());
  78 + return tv;
  79 + }
  80 +
  81 + /**
  82 + * 设置链接跳转与高亮样式
  83 + *
  84 + * @param url
  85 + * @return
  86 + */
  87 + private static ClickableSpan getClickableSpan(final String url) {
  88 + return new ClickableSpan() {
  89 + @Override
  90 + public void onClick(View widget) {
  91 + Uri uri = Uri.parse(url);
  92 + Context context = widget.getContext();
  93 + Intent intent = new Intent(Intent.ACTION_VIEW, uri);
  94 + intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
  95 + context.startActivity(intent);
  96 + }
  97 +
  98 + @Override
  99 + public void updateDrawState(TextPaint ds) {
  100 + super.updateDrawState(ds);
  101 + ds.setColor(Color.BLUE);
  102 + ds.setUnderlineText(false);
  103 + }
  104 + };
  105 + }
  106 +
  107 +}
  1 +package com.mang.xdy.demo.widget.emoji;
  2 +
  3 +import android.view.KeyEvent;
  4 +import android.widget.EditText;
  5 +
  6 +
  7 +
  8 +import java.util.ArrayList;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * emoji显示规则
  13 + *
  14 + * @author kymjs (http://www.kymjs.com/) on 6/8/15.
  15 + */
  16 +public enum DisplayRules {
  17 +
  18 + KJEMOJI0("[微笑]", 0xF0, 0x9F, 0x98, 0x81),
  19 + KJEMOJI1("[微笑]", 0xF0, 0x9F, 0x98, 0x82),
  20 + KJEMOJI2("[微笑]", 0xF0, 0x9F, 0x98, 0x83),
  21 + KJEMOJI3("[微笑]", 0xF0, 0x9F, 0x98, 0x84),
  22 + KJEMOJI4("[微笑]", 0xF0, 0x9F, 0x98, 0x85),
  23 + KJEMOJI5("[微笑]", 0xF0, 0x9F, 0x98, 0x86),
  24 + KJEMOJI6("[微笑]", 0xF0, 0x9F, 0x98, 0x89),
  25 + KJEMOJI7("[微笑]", 0xF0, 0x9F, 0x98, 0x8A),
  26 + KJEMOJI8("[微笑]", 0xF0, 0x9F, 0x98, 0x8B),
  27 + KJEMOJI9("[微笑]", 0xF0, 0x9F, 0x98, 0x8C),
  28 + KJEMOJI10("[微笑]", 0xF0, 0x9F, 0x98, 0x8D),
  29 + KJEMOJI11("[微笑]", 0xF0, 0x9F, 0x98, 0x8F),
  30 + KJEMOJI12("[微笑]", 0xF0, 0x9F, 0x98, 0x92),
  31 + KJEMOJI13("[微笑]", 0xF0, 0x9F, 0x98, 0x93),
  32 + KJEMOJI14("[微笑]", 0xF0, 0x9F, 0x98, 0x94),
  33 + KJEMOJI15("[微笑]", 0xF0, 0x9F, 0x98, 0x96),
  34 + KJEMOJI16("[微笑]", 0xF0, 0x9F, 0x98, 0x98),
  35 + KJEMOJI17("[微笑]", 0xF0, 0x9F, 0x98, 0x9A),
  36 + KJEMOJI18("[微笑]", 0xF0, 0x9F, 0x98, 0x9C),
  37 + KJEMOJI19("[微笑]", 0xF0, 0x9F, 0x98, 0x9D),
  38 + KJEMOJI20("[微笑]", 0xF0, 0x9F, 0x98, 0x9E),
  39 + KJEMOJI21("[微笑]", 0xF0, 0x9F, 0x98, 0xA0),
  40 + KJEMOJI22("[微笑]", 0xF0, 0x9F, 0x98, 0xA1),
  41 + KJEMOJI23("[微笑]", 0xF0, 0x9F, 0x98, 0xA2),
  42 + KJEMOJI24("[微笑]", 0xF0, 0x9F, 0x98, 0xA3),
  43 + KJEMOJI25("[微笑]", 0xF0, 0x9F, 0x98, 0xA4),
  44 + KJEMOJI26("[微笑]", 0xF0, 0x9F, 0x98, 0xA5),
  45 + BACK1("[删除]", 0xf0, 0x9f, 0x94, 0x99),
  46 + KJEMOJI27("[微笑]", 0xF0, 0x9F, 0x98, 0xA8),
  47 + KJEMOJI31("[微笑]", 0xF0, 0x9F, 0x98, 0xAD),
  48 + KJEMOJI32("[微笑]", 0xF0, 0x9F, 0x98, 0xB0),
  49 + KJEMOJI28("[微笑]", 0xF0, 0x9F, 0x98, 0xA9),
  50 + KJEMOJI29("[微笑]", 0xF0, 0x9F, 0x98, 0xAA),
  51 + KJEMOJI30("[微笑]", 0xF0, 0x9F, 0x98, 0xAB),
  52 + KJEMOJI33("[微笑]", 0xF0, 0x9F, 0x98, 0xB1),
  53 + KJEMOJI34("[微笑]", 0xF0, 0x9F, 0x98, 0xB2),
  54 + KJEMOJI35("[微笑]", 0xF0, 0x9F, 0x98, 0xB3),
  55 + KJEMOJI36("[微笑]", 0xF0, 0x9F, 0x98, 0xB5),
  56 + KJEMOJI37("[微笑]", 0xF0, 0x9F, 0x98, 0xB7),
  57 + KJEMOJI38("[微笑]", 0xF0, 0x9F, 0x98, 0x80),
  58 + KJEMOJI39("[微笑]", 0xF0, 0x9F, 0x98, 0x87),
  59 + KJEMOJI41("[微笑]", 0xF0, 0x9F, 0x98, 0x8E),
  60 + KJEMOJI42("[微笑]", 0xF0, 0x9F, 0x98, 0x90),
  61 + KJEMOJI43("[微笑]", 0xF0, 0x9F, 0x98, 0x91),
  62 + KJEMOJI44("[微笑]", 0xF0, 0x9F, 0x98, 0x95),
  63 + KJEMOJI45("[微笑]", 0xF0, 0x9F, 0x98, 0x97),
  64 + KJEMOJI46("[微笑]", 0xF0, 0x9F, 0x98, 0x99),
  65 + KJEMOJI47("[微笑]", 0xF0, 0x9F, 0x98, 0x9B),
  66 + KJEMOJI48("[微笑]", 0xF0, 0x9F, 0x98, 0x9F),
  67 + KJEMOJI49("[微笑]", 0xF0, 0x9F, 0x98, 0xA6),
  68 + KJEMOJI50("[微笑]", 0xF0, 0x9F, 0x98, 0xA7),
  69 + KJEMOJI51("[微笑]", 0xF0, 0x9F, 0x98, 0xAC),
  70 + KJEMOJI52("[微笑]", 0xF0, 0x9F, 0x98, 0xAE),
  71 + KJEMOJI53("[微笑]", 0xF0, 0x9F, 0x98, 0xAF),
  72 + KJEMOJI54("[微笑]", 0xF0, 0x9F, 0x98, 0xB4),
  73 + BACK2("[删除]", 0xf0, 0x9f, 0x94, 0x99),
  74 + KJEMOJI55("[微笑]", 0xF0, 0x9F, 0x98, 0xB6),
  75 +
  76 + CAT1("[微笑]", 0xF0, 0x9F, 0x98, 0xB8),
  77 + CAT2("[微笑]", 0xF0, 0x9F, 0x98, 0xB9),
  78 + CAT3("[微笑]", 0xF0, 0x9F, 0x98, 0xBA),
  79 + CAT4("[微笑]", 0xF0, 0x9F, 0x98, 0xBB),
  80 + CAT5("[微笑]", 0xF0, 0x9F, 0x98, 0xBC),
  81 + CAT6("[微笑]", 0xF0, 0x9F, 0x98, 0xBD),
  82 + CAT7("[微笑]", 0xF0, 0x9F, 0x98, 0xBE),
  83 + CAT8("[微笑]", 0xF0, 0x9F, 0x98, 0xBF),
  84 + CAT9("[微笑]", 0xF0, 0x9F, 0x99, 0x80),
  85 + BACK3("[删除]", 0xf0, 0x9f, 0x94, 0x99);
  86 +
  87 + private String emojiStr;
  88 + private byte value1;
  89 + private byte value2;
  90 + private byte value3;
  91 + private byte value4;
  92 + private byte[] value;
  93 +
  94 + DisplayRules(String emojiStr, int value1, int value2, int value3, int value4) {
  95 + this.emojiStr = emojiStr;
  96 + this.value1 = (byte) value1;
  97 + this.value2 = (byte) value2;
  98 + this.value3 = (byte) value3;
  99 + this.value4 = (byte) value4;
  100 + this.value = new byte[]{
  101 + this.value1, this.value2, this.value3, this.value4
  102 + };
  103 + }
  104 +
  105 + public static boolean isDeleteEmojicon(Emojicon emoji) {
  106 + if (emoji != null && emoji.getCode() != null) {
  107 + byte[] codes = emoji.getCode();
  108 + return (codes[0] == (byte) 0xf0 && codes[1] == (byte) 0x9f && codes[2] == (byte) 0x94
  109 + && codes[3] == (byte) 0x99);
  110 + } else {
  111 + return false;
  112 + }
  113 + }
  114 +
  115 + public static boolean isCustomDeleteEmojicon(String emoji) {
  116 + if (emoji != null) {
  117 + return (emoji.equals("[img:shanchu]"));
  118 + } else {
  119 + return false;
  120 + }
  121 + }
  122 +
  123 + public static List<Emojicon> getAllByType() {
  124 + List<Emojicon> datas = new ArrayList<Emojicon>(values().length);
  125 + for (DisplayRules data : values()) {
  126 + Emojicon emoji = new Emojicon();
  127 + emoji.setCode(data.value);
  128 + emoji.setName(data.emojiStr);
  129 + datas.add(emoji);
  130 + }
  131 + return datas;
  132 + }
  133 +
  134 + public static void backspace(EditText editText) {
  135 + if (editText == null) {
  136 + return;
  137 + }
  138 + KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0,
  139 + 0, KeyEvent.KEYCODE_ENDCALL);
  140 + editText.dispatchKeyEvent(event);
  141 + editText.setFocusable(true);
  142 + editText.setFocusableInTouchMode(true);
  143 + editText.requestFocus();
  144 + editText.findFocus();
  145 + editText.invalidate();
  146 + }
  147 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.emoji;
  17 +
  18 +import android.widget.AbsListView;
  19 +import android.widget.TextView;
  20 +
  21 +
  22 +import com.mang.xdy.demo.R;
  23 +
  24 +import org.kymjs.kjframe.widget.AdapterHolder;
  25 +import org.kymjs.kjframe.widget.KJAdapter;
  26 +
  27 +import java.util.Collection;
  28 +
  29 +/**
  30 + * emoji表情界面gridview适配器
  31 + *
  32 + * @author kymjs (http://www.kymjs.com/) on 6/8/15.
  33 + */
  34 +public class EmojiAdapter extends KJAdapter<String> {
  35 +
  36 + public EmojiAdapter(AbsListView view, Collection<String> mDatas) {
  37 + super(view, mDatas, R.layout.home_chat_item_emoji);
  38 + }
  39 +
  40 + @Override
  41 + public void convert(AdapterHolder adapterHolder, String emojicon, boolean b) {
  42 + TextView itemTvEmoji = adapterHolder.getView(R.id.itemEmoji);
  43 + itemTvEmoji.setText(emojicon);
  44 + }
  45 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.emoji;
  17 +
  18 +import android.app.Activity;
  19 +import android.os.Bundle;
  20 +import android.support.v4.view.PagerAdapter;
  21 +import android.support.v4.view.ViewPager;
  22 +import android.view.Gravity;
  23 +import android.view.LayoutInflater;
  24 +import android.view.View;
  25 +import android.view.ViewGroup;
  26 +import android.widget.AdapterView;
  27 +import android.widget.FrameLayout;
  28 +import android.widget.GridView;
  29 +import android.widget.LinearLayout;
  30 +import android.widget.RadioButton;
  31 +import android.widget.RadioGroup;
  32 +
  33 +
  34 +import com.mang.xdy.demo.R;
  35 +import com.mang.xdy.demo.widget.chat.OnOperationListener;
  36 +
  37 +import org.kymjs.kjframe.ui.SupportFragment;
  38 +
  39 +import java.util.List;
  40 +
  41 +
  42 +/**
  43 + * Emoji表情分类的显示
  44 + *
  45 + * @author kymjs (http://www.kymjs.com/) on 6/8/15.
  46 + */
  47 +public class EmojiPageFragment extends SupportFragment {
  48 +
  49 + private static final int ITEM_PAGE_COUNT = 28;
  50 +
  51 + private ViewPager mPagerFace;
  52 + private LinearLayout pagePointLayout;
  53 +
  54 + private Activity aty;
  55 + private GridView[] allPageViews;
  56 + private RadioButton[] pointViews;
  57 + private OnOperationListener listener;
  58 +
  59 + private List<String> datas;
  60 +
  61 + @Override
  62 + protected View inflaterView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
  63 + aty = getActivity();
  64 + View rootView = layoutInflater.inflate(R.layout.home_chat_frag_face, null);
  65 + return rootView;
  66 + }
  67 +
  68 + @Override
  69 + protected void initData() {
  70 + super.initData();
  71 + datas=EmojiconHandler.mEmoticons;
  72 + // datas = DisplayRules.getAllByType();
  73 + }
  74 +
  75 +
  76 + @Override
  77 + protected void initWidget(View rootView) {
  78 + mPagerFace = (ViewPager) rootView.findViewById(R.id.frag_pager_face);
  79 + pagePointLayout = (LinearLayout) rootView.findViewById(R.id.frag_point);
  80 +
  81 + int total = datas.size();
  82 + int pages = total / ITEM_PAGE_COUNT
  83 + + (total % ITEM_PAGE_COUNT == 0 ? 0 : 1);
  84 +
  85 + allPageViews = new GridView[pages];
  86 + pointViews = new RadioButton[pages];
  87 +
  88 + for (int x = 0; x < pages; x++) {
  89 + int start = x * ITEM_PAGE_COUNT;
  90 + int end = (start + ITEM_PAGE_COUNT) > total ? total
  91 + : (start + ITEM_PAGE_COUNT);
  92 + final List<String> itemDatas = datas.subList(start, end);
  93 + GridView view = new GridView(aty);
  94 + EmojiAdapter faceAdapter = new EmojiAdapter(view, itemDatas);
  95 +
  96 + view.setNumColumns(7);
  97 + view.setHorizontalSpacing(1);
  98 + view.setVerticalSpacing(1);
  99 + view.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
  100 + view.setCacheColorHint(0);
  101 + view.setPadding(2, 0, 2, 0);
  102 + view.setBackgroundResource(android.R.color.transparent);
  103 + view.setSelector(android.R.color.transparent);
  104 + view.setVerticalScrollBarEnabled(false);
  105 + view.setGravity(Gravity.CENTER);
  106 + view.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
  107 + FrameLayout.LayoutParams.WRAP_CONTENT));
  108 + view.setAdapter(faceAdapter);
  109 +
  110 + view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  111 + @Override
  112 + public void onItemClick(AdapterView<?> parent, View view,
  113 + int position, long id) {
  114 + if (listener != null) {
  115 + String emoji = itemDatas.get(position);
  116 + if (EmojiconHandler.isCustomDeleteEmojicon(emoji)) {
  117 + listener.selectedBackSpace(emoji);
  118 + } else {
  119 + listener.selectedEmoji(emoji);
  120 + }
  121 + }
  122 + }
  123 + });
  124 + allPageViews[x] = view;
  125 +
  126 + RadioButton tip = new RadioButton(aty);
  127 + tip.setBackgroundResource(R.drawable.home_selector_chat_emoji_btn);
  128 + RadioGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams(
  129 + 8, 8);
  130 + layoutParams.leftMargin = 10;
  131 + pagePointLayout.addView(tip, layoutParams);
  132 + if (x == 0) {
  133 + tip.setChecked(true);
  134 + }
  135 + pointViews[x] = tip;
  136 + }
  137 +
  138 + PagerAdapter facePagerAdapter = new FacePagerAdapter(allPageViews);
  139 + mPagerFace.setAdapter(facePagerAdapter);
  140 + mPagerFace.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
  141 +
  142 + @Override
  143 + public void onPageSelected(int index) {
  144 + pointViews[index].setChecked(true);
  145 + }
  146 +
  147 + @Override
  148 + public void onPageScrolled(int arg0, float arg1, int arg2) {
  149 + }
  150 +
  151 + @Override
  152 + public void onPageScrollStateChanged(int arg0) {
  153 + }
  154 + });
  155 + }
  156 +
  157 + public class FacePagerAdapter extends PagerAdapter {
  158 + private final GridView[] gridViewList;
  159 +
  160 + public FacePagerAdapter(GridView[] gridViewList) {
  161 + this.gridViewList = gridViewList;
  162 + }
  163 +
  164 + @Override
  165 + public int getCount() {
  166 + return gridViewList.length;
  167 + }
  168 +
  169 + @Override
  170 + public boolean isViewFromObject(View arg0, Object arg1) {
  171 + return arg0 == arg1;
  172 + }
  173 +
  174 + @Override
  175 + public int getItemPosition(Object object) {
  176 + return super.getItemPosition(object);
  177 + }
  178 +
  179 + @Override
  180 + public void destroyItem(View arg0, int arg1, Object arg2) {
  181 + ((ViewPager) arg0).removeView(gridViewList[arg1]);
  182 + }
  183 +
  184 + @Override
  185 + public Object instantiateItem(View arg0, int arg1) {
  186 + ((ViewPager) arg0).addView(gridViewList[arg1]);
  187 + return gridViewList[arg1];
  188 + }
  189 + }
  190 +
  191 + public void setOnOperationListener(OnOperationListener onOperationListener) {
  192 + this.listener = onOperationListener;
  193 + }
  194 +}
  1 +/*
  2 + * Copyright (c) 2015, 张涛.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.mang.xdy.demo.widget.emoji;
  17 +
  18 +/**
  19 + * emoji表情的javabean
  20 + *
  21 + * @author kymjs (http://www.kymjs.com/) on 6/8/15.
  22 + */
  23 +public class Emojicon {
  24 + private String name; //在网络传递中的值
  25 + private byte[] code; //在系统中所代表的值
  26 + private String value; //code转换为String的值
  27 +
  28 + public String getName() {
  29 + return name;
  30 + }
  31 +
  32 + public void setName(String name) {
  33 + this.name = name;
  34 + }
  35 +
  36 + public byte[] getCode() {
  37 + return code;
  38 + }
  39 +
  40 + public void setCode(byte[] code) {
  41 + this.code = code;
  42 + }
  43 +
  44 + public void setValue(String value) {
  45 + this.value = value;
  46 + }
  47 +
  48 + /**
  49 + * @return code转换为String的值
  50 + */
  51 + public String getValue() {
  52 + if (code == null) {
  53 + return null;
  54 + } else {
  55 + return new String(code);
  56 + }
  57 + }
  58 +}
  1 +package com.mang.xdy.demo.widget.emoji;
  2 +
  3 +
  4 +import com.mang.xdy.demo.R;
  5 +
  6 +import java.util.ArrayList;
  7 +import java.util.HashMap;
  8 +import java.util.List;
  9 +import java.util.Map;
  10 +
  11 +/**
  12 + * Created by Admin on 2017/3/29.
  13 + */
  14 +
  15 +public class EmojiconHandler {
  16 + public static List<String> mEmoticons = new ArrayList<String>();
  17 + public static Map<String, Integer> mEmoticonsId = new HashMap<String, Integer>();
  18 +
  19 + static {
  20 + mEmoticonsId.put("[img:weixiao]", R.drawable.weixiao);
  21 + mEmoticons.add("[img:weixiao]");
  22 + mEmoticonsId.put("[img:piezui]", R.drawable.piezui);
  23 + mEmoticons.add("[img:piezui]");
  24 + mEmoticonsId.put("[img:aimu]", R.drawable.aimu);
  25 + mEmoticons.add("[img:aimu]");
  26 + mEmoticonsId.put("[img:fadai]", R.drawable.fadai);
  27 + mEmoticons.add("[img:fadai]");
  28 + mEmoticonsId.put("[img:fanu]", R.drawable.fanu);
  29 + mEmoticons.add("[img:fanu]");
  30 + mEmoticonsId.put("[img:mojing]", R.drawable.mojing);
  31 + mEmoticons.add("[img:mojing]");
  32 + mEmoticonsId.put("[img:liulei]", R.drawable.liulei);
  33 + mEmoticons.add("[img:liulei]");
  34 + mEmoticonsId.put("[img:jingya]", R.drawable.jingya);
  35 + mEmoticons.add("[img:jingya]");
  36 + mEmoticonsId.put("[img:daxiao]", R.drawable.daxiao);
  37 + mEmoticons.add("[img:daxiao]");
  38 + mEmoticonsId.put("[img:ganga]", R.drawable.ganga);
  39 + mEmoticons.add("[img:ganga]");
  40 + mEmoticonsId.put("[img:daku]", R.drawable.daku);
  41 + mEmoticons.add("[img:daku]");
  42 + mEmoticonsId.put("[img:shuijiao]", R.drawable.shuijiao);
  43 + mEmoticons.add("[img:shuijiao]");
  44 + mEmoticonsId.put("[img:bizui]", R.drawable.bizui);
  45 + mEmoticons.add("[img:bizui]");
  46 + mEmoticonsId.put("[img:meiyan]", R.drawable.meiyan);
  47 + mEmoticons.add("[img:meiyan]");
  48 + mEmoticonsId.put("[img:yumen]", R.drawable.yumen);
  49 + mEmoticons.add("[img:yumen]");
  50 + mEmoticonsId.put("[img:cool]", R.drawable.cool);
  51 + mEmoticons.add("[img:cool]");
  52 + mEmoticonsId.put("[img:zhemo]", R.drawable.zhemo);
  53 + mEmoticons.add("[img:zhemo]");
  54 + mEmoticonsId.put("[img:tu]", R.drawable.tu);
  55 + mEmoticons.add("[img:tu]");
  56 + mEmoticonsId.put("[img:touxiao]", R.drawable.touxiao);
  57 + mEmoticons.add("[img:touxiao]");
  58 + mEmoticonsId.put("[img:guai]", R.drawable.guai);
  59 + mEmoticons.add("[img:guai]");
  60 + mEmoticonsId.put("[img:baiyan]", R.drawable.baiyan);
  61 + mEmoticons.add("[img:baiyan]");
  62 + mEmoticonsId.put("[img:aoman]", R.drawable.aoman);
  63 + mEmoticons.add("[img:aoman]");
  64 + mEmoticonsId.put("[img:jiew]", R.drawable.jiew);
  65 + mEmoticons.add("[img:jiew]");
  66 + mEmoticonsId.put("[img:kun]", R.drawable.kun);
  67 + mEmoticons.add("[img:kun]");
  68 + mEmoticonsId.put("[img:jingkong]", R.drawable.jingkong);
  69 + mEmoticons.add("[img:jingkong]");
  70 + mEmoticonsId.put("[img:liuhan]", R.drawable.liuhan);
  71 + mEmoticons.add("[img:liuhan]");
  72 + mEmoticonsId.put("[img:hanxiao]", R.drawable.hanxiao);
  73 + mEmoticons.add("[img:hanxiao]");
  74 + mEmoticonsId.put("[img:shanchu]", R.drawable.orca_emoji_backspace_back_normal);
  75 + mEmoticons.add("[img:shanchu]");
  76 + mEmoticonsId.put("[img:hanxiao]", R.drawable.hanxiao);
  77 + mEmoticons.add("[img:hanxiao]");
  78 + //orca_emoji_backspace_back_normal
  79 + mEmoticonsId.put("[img:dabing]", R.drawable.dabing);
  80 + mEmoticons.add("[img:dabing]");
  81 + mEmoticonsId.put("[img:fendou]", R.drawable.fendou);
  82 + mEmoticons.add("[img:fendou]");
  83 + mEmoticonsId.put("[img:zhouma]", R.drawable.zhouma);
  84 + mEmoticons.add("[img:zhouma]");
  85 + mEmoticonsId.put("[img:yiwen]", R.drawable.yiwen);
  86 + mEmoticons.add("[img:yiwen]");
  87 + mEmoticonsId.put("[img:yun]", R.drawable.yun);
  88 + mEmoticons.add("[img:yun]");
  89 + mEmoticonsId.put("[img:shuai]", R.drawable.shuai);
  90 + mEmoticons.add("[img:shuai]");
  91 + mEmoticonsId.put("[img:kulou]", R.drawable.kulou);
  92 + mEmoticons.add("[img:kulou]");
  93 + mEmoticonsId.put("[img:zaijian]", R.drawable.zaijian);
  94 + mEmoticons.add("[img:zaijian]");
  95 + mEmoticonsId.put("[img:cahan]", R.drawable.cahan);
  96 + mEmoticons.add("[img:cahan]");
  97 +
  98 + mEmoticonsId.put("[img:koubi]", R.drawable.koubi);
  99 + mEmoticons.add("[img:koubi]");
  100 + mEmoticonsId.put("[img:guzhang]", R.drawable.guzhang);
  101 + mEmoticons.add("[img:guzhang]");
  102 + mEmoticonsId.put("[img:qiu]", R.drawable.qiu);
  103 + mEmoticons.add("[img:qiu]");
  104 + mEmoticonsId.put("[img:huaixiao]", R.drawable.huaixiao);
  105 + mEmoticons.add("[img:huaixiao]");
  106 + mEmoticonsId.put("[img:zuohh]", R.drawable.zuohh);
  107 + mEmoticons.add("[img:zuohh]");
  108 + mEmoticonsId.put("[img:youhh]", R.drawable.youhh);
  109 + mEmoticons.add("[img:youhh]");
  110 + mEmoticonsId.put("[img:haqi]", R.drawable.haqi);
  111 + mEmoticons.add("[img:haqi]");
  112 + mEmoticonsId.put("[img:bishi]", R.drawable.bishi);
  113 + mEmoticons.add("[img:bishi]");
  114 + mEmoticonsId.put("[img:weiqu]", R.drawable.weiqu);
  115 + mEmoticons.add("[img:weiqu]");
  116 + mEmoticonsId.put("[img:kuaikl]", R.drawable.kuaikl);
  117 + mEmoticons.add("[img:kuaikl]");
  118 + mEmoticonsId.put("[img:yinxian]", R.drawable.yinxian);
  119 + mEmoticons.add("[img:yinxian]");
  120 + mEmoticonsId.put("[img:qinqin]", R.drawable.qinqin);
  121 + mEmoticons.add("[img:qinqin]");
  122 + mEmoticonsId.put("[img:kelian]", R.drawable.kelian);
  123 + mEmoticons.add("[img:kelian]");
  124 +
  125 + mEmoticonsId.put("[img:xigua]", R.drawable.xigua);
  126 + mEmoticons.add("[img:xigua]");
  127 + mEmoticonsId.put("[img:pijiu]", R.drawable.pijiu);
  128 + mEmoticons.add("[img:pijiu]");
  129 + mEmoticonsId.put("[img:kafei]", R.drawable.kafei);
  130 + mEmoticons.add("[img:kafei]");
  131 + mEmoticonsId.put("[img:hua]", R.drawable.hua);
  132 + mEmoticons.add("[img:hua]");
  133 + mEmoticonsId.put("[img:shanchu]", R.drawable.orca_emoji_backspace_back_normal);
  134 + mEmoticons.add("[img:shanchu]");
  135 + mEmoticonsId.put("[img:tiaoxie]", R.drawable.tiaoxie);
  136 + mEmoticons.add("[img:tiaoxie]");
  137 +
  138 +
  139 + mEmoticonsId.put("[img:xin]", R.drawable.xin);
  140 + mEmoticons.add("[img:xin]");
  141 + mEmoticonsId.put("[img:dangao]", R.drawable.dangao);
  142 + mEmoticons.add("[img:dangao]");
  143 + mEmoticonsId.put("[img:yue]", R.drawable.yue);
  144 + mEmoticons.add("[img:yue]");
  145 + mEmoticonsId.put("[img:sun]", R.drawable.sun);
  146 + mEmoticons.add("[img:sun]");
  147 + mEmoticonsId.put("[img:qiang]", R.drawable.qiang);
  148 + mEmoticons.add("[img:qiang]");
  149 + mEmoticonsId.put("[img:ruo]", R.drawable.ruo);
  150 + mEmoticons.add("[img:ruo]");
  151 + mEmoticonsId.put("[img:woshou]", R.drawable.woshou);
  152 + mEmoticons.add("[img:woshou]");
  153 + mEmoticonsId.put("[img:baoquan]", R.drawable.baoquan);
  154 + mEmoticons.add("[img:baoquan]");
  155 + mEmoticonsId.put("[img:zancheng]", R.drawable.zancheng);
  156 + mEmoticons.add("[img:zancheng]");
  157 + mEmoticonsId.put("[img:shanchu]", R.drawable.orca_emoji_backspace_back_normal);
  158 + mEmoticons.add("[img:shanchu]");
  159 + }
  160 + public static boolean isCustomDeleteEmojicon(String emoji) {
  161 + if (emoji != null) {
  162 + return (emoji.equals("[img:shanchu]"));
  163 + } else {
  164 + return false;
  165 + }
  166 + }
  167 +}
  1 +package com.mang.xdy.demo.widget.emoji;
  2 +
  3 +import android.content.Context;
  4 +import android.content.res.TypedArray;
  5 +import android.graphics.Bitmap;
  6 +import android.graphics.BitmapFactory;
  7 +import android.text.Spannable;
  8 +import android.text.SpannableStringBuilder;
  9 +import android.text.TextUtils;
  10 +import android.text.style.ImageSpan;
  11 +import android.util.AttributeSet;
  12 +import android.widget.EditText;
  13 +
  14 +import java.util.regex.Matcher;
  15 +import java.util.regex.Pattern;
  16 +
  17 +
  18 +public class EmoticonsEditText extends EditText {
  19 +
  20 + private int mEmojiconSize;
  21 + private int mEmojiconTextSize;
  22 + private boolean mUseSystemDefault = false;
  23 +
  24 + public EmoticonsEditText(Context context) {
  25 + super(context);
  26 + mEmojiconSize = (int) getTextSize();
  27 + mEmojiconTextSize = (int) getTextSize();
  28 + }
  29 +
  30 + public EmoticonsEditText(Context context, AttributeSet attrs, int defStyle) {
  31 + super(context, attrs, defStyle);
  32 + init(attrs);
  33 + }
  34 +
  35 + public EmoticonsEditText(Context context, AttributeSet attrs) {
  36 + super(context, attrs);
  37 + init(attrs);
  38 + }
  39 +
  40 + private void init(AttributeSet attrs) {
  41 + TypedArray a = getContext().obtainStyledAttributes(attrs, com.rockerhieu.emojicon.R.styleable.Emojicon);
  42 + mEmojiconSize = (int) a.getDimension(com.rockerhieu.emojicon.R.styleable.Emojicon_emojiconSize, getTextSize());
  43 + mUseSystemDefault = a.getBoolean(com.rockerhieu.emojicon.R.styleable.Emojicon_emojiconUseSystemDefault, false);
  44 + a.recycle();
  45 + mEmojiconTextSize = (int) getTextSize();
  46 + //setText(getText());
  47 + }
  48 +
  49 + @Override
  50 + public void setText(CharSequence text, BufferType type) {
  51 + if (!TextUtils.isEmpty(text)) {
  52 + super.setText(replace(text), type);
  53 + /*setFocusable(true);
  54 + setFocusableInTouchMode(true);
  55 + requestFocus();
  56 + findFocus();
  57 + invalidate();*/
  58 + } else {
  59 + super.setText(text, type);
  60 + }
  61 + }
  62 +
  63 + private Pattern buildPattern() {
  64 + StringBuilder patternString = new StringBuilder(EmojiconHandler.mEmoticons.size() * 3);
  65 + patternString.append('(');
  66 + for (int i = 0; i < EmojiconHandler.mEmoticons.size(); i++) {
  67 + String s = EmojiconHandler.mEmoticons.get(i);
  68 + patternString.append(Pattern.quote(s));
  69 + patternString.append('|');
  70 + }
  71 + patternString.replace(patternString.length() - 1,
  72 + patternString.length(), ")");
  73 + return Pattern.compile(patternString.toString());
  74 + }
  75 +
  76 + private CharSequence replace(CharSequence text) {
  77 + try {
  78 + SpannableStringBuilder builder = new SpannableStringBuilder(text);
  79 + Pattern pattern = buildPattern();
  80 + Matcher matcher = pattern.matcher(text);
  81 + while (matcher.find()) {
  82 + if (EmojiconHandler.mEmoticonsId.containsKey(matcher.group())) {
  83 + int id = EmojiconHandler.mEmoticonsId.get(matcher.group());
  84 + Bitmap bitmap = BitmapFactory.decodeResource(
  85 + getResources(), id);
  86 + if (bitmap != null) {
  87 + ImageSpan span = new ImageSpan(getContext(), bitmap);
  88 + builder.setSpan(span, matcher.start(), matcher.end(),
  89 + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  90 + }
  91 + }
  92 + }
  93 + return builder;
  94 + } catch (Exception e) {
  95 + return text;
  96 + }
  97 + }
  98 +
  99 +}
  1 +package com.mang.xdy.demo.widget.emoji;
  2 +
  3 +import android.content.Context;
  4 +import android.content.res.TypedArray;
  5 +import android.graphics.Bitmap;
  6 +import android.graphics.BitmapFactory;
  7 +import android.text.Spannable;
  8 +import android.text.SpannableStringBuilder;
  9 +import android.text.TextUtils;
  10 +import android.text.style.ImageSpan;
  11 +import android.util.AttributeSet;
  12 +import android.widget.TextView;
  13 +
  14 +import java.util.regex.Matcher;
  15 +import java.util.regex.Pattern;
  16 +
  17 +public class EmoticonsTextView extends TextView {
  18 +
  19 + private int mEmojiconSize;
  20 + private int mEmojiconTextSize;
  21 + private int mTextStart = 0;
  22 + private int mTextLength = -1;
  23 + private boolean mUseSystemDefault = false;
  24 +
  25 + public EmoticonsTextView(Context context) {
  26 + super(context);
  27 + init(null);
  28 + }
  29 +
  30 + private void init(AttributeSet attrs) {
  31 + mEmojiconTextSize = (int) getTextSize();
  32 + if (attrs == null) {
  33 + mEmojiconSize = (int) getTextSize();
  34 + } else {
  35 + TypedArray a = getContext().obtainStyledAttributes(attrs, com.rockerhieu.emojicon.R.styleable.Emojicon);
  36 + mEmojiconSize = (int) a.getDimension(com.rockerhieu.emojicon.R.styleable.Emojicon_emojiconSize, getTextSize());
  37 + mTextStart = a.getInteger(com.rockerhieu.emojicon.R.styleable.Emojicon_emojiconTextStart, 0);
  38 + mTextLength = a.getInteger(com.rockerhieu.emojicon.R.styleable.Emojicon_emojiconTextLength, -1);
  39 + mUseSystemDefault = a.getBoolean(com.rockerhieu.emojicon.R.styleable.Emojicon_emojiconUseSystemDefault, false);
  40 + a.recycle();
  41 + }
  42 + setText(getText());
  43 + }
  44 +
  45 + public EmoticonsTextView(Context context, AttributeSet attrs, int defStyle) {
  46 + super(context, attrs, defStyle);
  47 + init(attrs);
  48 + }
  49 +
  50 + public EmoticonsTextView(Context context, AttributeSet attrs) {
  51 + super(context, attrs);
  52 + init(attrs);
  53 + }
  54 +
  55 + @Override
  56 + public void setText(CharSequence text, BufferType type) {
  57 + if (!TextUtils.isEmpty(text)) {
  58 + // SpannableStringBuilder builder = new SpannableStringBuilder(text);
  59 + // com.rockerhieu.emojicon.EmojiconHandler.addEmojis(getContext(), builder, mEmojiconSize, mEmojiconTextSize, mTextStart, mTextLength, mUseSystemDefault);
  60 + // text = builder;
  61 + super.setText(replace(text), type);
  62 + } else {
  63 + super.setText(text, type);
  64 + }
  65 + }
  66 +
  67 + private Pattern buildPattern() {
  68 + StringBuilder patternString = new StringBuilder(
  69 + EmojiconHandler.mEmoticons.size() * 3);
  70 + patternString.append('(');
  71 + for (int i = 0; i < EmojiconHandler.mEmoticons.size(); i++) {
  72 + String s = EmojiconHandler.mEmoticons.get(i);
  73 + patternString.append(Pattern.quote(s));
  74 + patternString.append('|');
  75 + }
  76 + patternString.replace(patternString.length() - 1,
  77 + patternString.length(), ")");
  78 + return Pattern.compile(patternString.toString());
  79 + }
  80 +
  81 + private CharSequence replace(CharSequence text) {
  82 + try {
  83 + SpannableStringBuilder builder = new SpannableStringBuilder(text);
  84 + Pattern pattern = buildPattern();
  85 + Matcher matcher = pattern.matcher(text);
  86 + while (matcher.find()) {
  87 + if (EmojiconHandler.mEmoticonsId.containsKey(matcher.group())) {
  88 + int id = EmojiconHandler.mEmoticonsId.get(matcher.group());
  89 + Bitmap bitmap = BitmapFactory.decodeResource(
  90 + getResources(), id);
  91 + if (bitmap != null) {
  92 + ImageSpan span = new ImageSpan(getContext(), bitmap);
  93 + builder.setSpan(span, matcher.start(), matcher.end(),
  94 + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  95 + }
  96 + }
  97 + }
  98 + return builder;
  99 + } catch (Exception e) {
  100 + return text;
  101 + }
  102 + }
  103 +
  104 + /**
  105 + * Set the size of emojicon in pixels.
  106 + */
  107 + public void setEmojiconSize(int pixels) {
  108 + mEmojiconSize = pixels;
  109 + super.setText(getText());
  110 + }
  111 +
  112 + /**
  113 + * Set whether to use system default emojicon
  114 + */
  115 + public void setUseSystemDefault(boolean useSystemDefault) {
  116 + mUseSystemDefault = useSystemDefault;
  117 + }
  118 +}