正在显示
100 个修改的文件
包含
4213 行增加
和
161 行删除
| @@ -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 | +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 | +} |
MyApplication/XdyDemo/src/main/java/com/mang/xdy/demo/widget/chat/ChatFunctionFragment.java
0 → 100644
| 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 | +} |
MyApplication/XdyDemo/src/main/java/com/mang/xdy/demo/widget/chat/OnOperationListener.java
0 → 100644
| 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 | +} |
MyApplication/XdyDemo/src/main/java/com/mang/xdy/demo/widget/chat/PagerSlidingTabStrip.java
0 → 100644
| 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 | +} |
MyApplication/XdyDemo/src/main/java/com/mang/xdy/demo/widget/chat/SoftKeyboardStateHelper.java
0 → 100644
| 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 | +} |
MyApplication/XdyDemo/src/main/java/com/mang/xdy/demo/widget/emoji/EmojiPageFragment.java
0 → 100644
| 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 | +} |
MyApplication/XdyDemo/src/main/java/com/mang/xdy/demo/widget/emoji/EmoticonsEditText.java
0 → 100644
| 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 | +} |
MyApplication/XdyDemo/src/main/java/com/mang/xdy/demo/widget/emoji/EmoticonsTextView.java
0 → 100644
| 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 | +} |
342 字节
4.5 KB
4.6 KB
4.6 KB
4.8 KB
5.1 KB
5.1 KB
5.1 KB
826 字节
4.8 KB
4.5 KB
4.7 KB
4.5 KB
5.1 KB
4.9 KB
5.6 KB
4.8 KB
4.8 KB
4.5 KB
5.1 KB
4.7 KB
5.2 KB
3.0 KB
4.9 KB
4.9 KB
4.9 KB
4.9 KB
5.2 KB
5.4 KB
4.5 KB
4.7 KB
4.0 KB
4.5 KB
4.5 KB
4.2 KB
4.6 KB
4.3 KB
4.4 KB
4.8 KB
4.9 KB
3.8 KB
4.6 KB
5.3 KB
3.8 KB
1.6 KB
5.3 KB
5.0 KB
5.0 KB
3.8 KB
5.3 KB
4.9 KB
5.0 KB
4.5 KB
4.6 KB
4.5 KB
3.8 KB
4.5 KB
5.7 KB
4.5 KB
5.1 KB
4.6 KB
4.7 KB
5.2 KB
4.8 KB
5.2 KB
5.1 KB
4.5 KB
-
请 注册 或 登录 后发表评论