├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── TigerLibrary
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── cn
│ │ └── ittiger
│ │ ├── app
│ │ └── AppContext.java
│ │ ├── base
│ │ ├── BaseActivity.java
│ │ └── BaseFragment.java
│ │ ├── ui
│ │ ├── BaseKeyboardLayout.java
│ │ ├── LoadingView.java
│ │ └── NoHorizontalScrollViewPager.java
│ │ └── util
│ │ ├── ActivityUtil.java
│ │ ├── AppInfo.java
│ │ ├── AppUtil.java
│ │ ├── BitmapUtil.java
│ │ ├── ByteUtil.java
│ │ ├── DateUtil.java
│ │ ├── DisplayUtils.java
│ │ ├── FileUtil.java
│ │ ├── HexUtil.java
│ │ ├── KeyboardUtil.java
│ │ ├── PageLoadingHelper.java
│ │ ├── PreferenceHelper.java
│ │ ├── SdCardUtil.java
│ │ ├── UIUtil.java
│ │ ├── UnCaughtCrashExceptionHandler.java
│ │ ├── ValueUtil.java
│ │ └── cipher
│ │ ├── Base64Cipher.java
│ │ ├── Cipher.java
│ │ ├── Decrypt.java
│ │ └── Encrypt.java
│ └── res
│ ├── layout
│ ├── base_layout.xml
│ └── loading_failed_layout.xml
│ └── values
│ ├── ids.xml
│ └── strings.xml
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── TigerDB.jar
├── problem.md
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── cn
│ │ └── ittiger
│ │ └── im
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── cn
│ │ │ └── ittiger
│ │ │ └── im
│ │ │ ├── activity
│ │ │ ├── AboutActivity.java
│ │ │ ├── AccountMngActivity.java
│ │ │ ├── AddFriendActivity.java
│ │ │ ├── ChatActivity.java
│ │ │ ├── CreateMultiChatActivity.java
│ │ │ ├── LoginActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MultiChatActivity.java
│ │ │ ├── RegisterActivity.java
│ │ │ ├── WebPageActivity.java
│ │ │ └── base
│ │ │ │ ├── BaseChatActivity.java
│ │ │ │ └── IMBaseActivity.java
│ │ │ ├── adapter
│ │ │ ├── BaseViewAdapter.java
│ │ │ ├── ChatAdapter.java
│ │ │ ├── ChatRecordAdapter.java
│ │ │ ├── CheckableContactAdapter.java
│ │ │ ├── ContactAdapter.java
│ │ │ ├── EmotionAdapter.java
│ │ │ ├── EmotionViewPagerAdapter.java
│ │ │ └── viewholder
│ │ │ │ ├── ChatRecordViewHolder.java
│ │ │ │ ├── ContactIndexViewHolder.java
│ │ │ │ ├── ContactViewHolder.java
│ │ │ │ └── CreateMultiChatViewHolder.java
│ │ │ ├── app
│ │ │ ├── App.java
│ │ │ └── IDbApplication.java
│ │ │ ├── bean
│ │ │ ├── ChatMessage.java
│ │ │ ├── ChatRecord.java
│ │ │ ├── ChatUser.java
│ │ │ ├── CheckableContactEntity.java
│ │ │ ├── ContactEntity.java
│ │ │ ├── ContactMenuEntity.java
│ │ │ ├── LoginResult.java
│ │ │ ├── MultiChatRoom.java
│ │ │ └── User.java
│ │ │ ├── constant
│ │ │ ├── Constant.java
│ │ │ ├── EmotionType.java
│ │ │ ├── FileLoadState.java
│ │ │ ├── KeyBoardMoreFunType.java
│ │ │ └── MessageType.java
│ │ │ ├── decoration
│ │ │ ├── CommonItemDecoration.java
│ │ │ ├── CommonVerticalItemDecoration.java
│ │ │ └── ContactItemDecoration.java
│ │ │ ├── fragment
│ │ │ ├── BaseEmotionFragment.java
│ │ │ ├── ContactFragment.java
│ │ │ ├── EmotionFragment.java
│ │ │ └── MessageFragment.java
│ │ │ ├── smack
│ │ │ ├── MultiChatInvitationListener.java
│ │ │ ├── MultiChatMessageListener.java
│ │ │ ├── SmackChatManagerListener.java
│ │ │ ├── SmackConnectionListener.java
│ │ │ ├── SmackListenerManager.java
│ │ │ ├── SmackManager.java
│ │ │ └── SmackMultiChatManager.java
│ │ │ ├── ui
│ │ │ ├── ChatPromptDialog.java
│ │ │ ├── CircleImageView.java
│ │ │ ├── ClearEditText.java
│ │ │ ├── FragmentSaveStateTabHost.java
│ │ │ ├── RecordingVoiceView.java
│ │ │ ├── keyboard
│ │ │ │ ├── ChatKeyboard.java
│ │ │ │ ├── KeyBoardMoreFunView.java
│ │ │ │ ├── KeyBoardToolBoxView.java
│ │ │ │ └── emotion
│ │ │ │ │ ├── EmotionIndicatorView.java
│ │ │ │ │ ├── EmotionItemClickListener.java
│ │ │ │ │ └── KeyBoardEmotionView.java
│ │ │ └── recyclerview
│ │ │ │ ├── CommonRecyclerView.java
│ │ │ │ ├── HeaderAndFooterAdapter.java
│ │ │ │ └── ViewHolder.java
│ │ │ └── util
│ │ │ ├── AppFileHelper.java
│ │ │ ├── ChatTimeUtil.java
│ │ │ ├── DBHelper.java
│ │ │ ├── DBQueryHelper.java
│ │ │ ├── EmotionDataHelper.java
│ │ │ ├── EmotionUtil.java
│ │ │ ├── IMUtil.java
│ │ │ ├── ImageLoaderHelper.java
│ │ │ ├── IntentHelper.java
│ │ │ ├── LoginHelper.java
│ │ │ ├── RecordVoiceManager.java
│ │ │ └── ShareHelper.java
│ └── res
│ │ ├── color
│ │ └── tabbar_text_color.xml
│ │ ├── drawable-hdpi
│ │ ├── avatar.png
│ │ ├── bg_launcher.jpeg
│ │ ├── pic_default.png
│ │ ├── tigerframe_edittext_clear.png
│ │ ├── tigerframe_icon_back_btn_normal.png
│ │ └── tigerframe_icon_back_btn_pressed.png
│ │ ├── drawable-xxhdpi
│ │ ├── about_img.jpg
│ │ ├── avatar.png
│ │ ├── chat_from_bg_normal.9.png
│ │ ├── chat_from_bg_pressed.9.png
│ │ ├── chat_to_bg_normal.9.png
│ │ ├── chat_to_bg_pressed.9.png
│ │ ├── d_aini.png
│ │ ├── d_aoteman.png
│ │ ├── d_baibai.png
│ │ ├── d_beishang.png
│ │ ├── d_bishi.png
│ │ ├── d_bizui.png
│ │ ├── d_chanzui.png
│ │ ├── d_chijing.png
│ │ ├── d_dahaqi.png
│ │ ├── d_dalian.png
│ │ ├── d_ding.png
│ │ ├── d_doge.png
│ │ ├── d_fangdumianju.png
│ │ ├── d_feizao.png
│ │ ├── d_ganmao.png
│ │ ├── d_guzhang.png
│ │ ├── d_haha.png
│ │ ├── d_haixiu.png
│ │ ├── d_han.png
│ │ ├── d_hehe.png
│ │ ├── d_heixian.png
│ │ ├── d_heng.png
│ │ ├── d_huaxin.png
│ │ ├── d_jiyan.png
│ │ ├── d_keai.png
│ │ ├── d_kelian.png
│ │ ├── d_ku.png
│ │ ├── d_kun.png
│ │ ├── d_landelini.png
│ │ ├── d_lang.png
│ │ ├── d_lei.png
│ │ ├── d_miao.png
│ │ ├── d_nanhaier.png
│ │ ├── d_nu.png
│ │ ├── d_numa.png
│ │ ├── d_nvhaier.png
│ │ ├── d_qian.png
│ │ ├── d_qinqin.png
│ │ ├── d_shayan.png
│ │ ├── d_shengbing.png
│ │ ├── d_shenshou.png
│ │ ├── d_shiwang.png
│ │ ├── d_shuai.png
│ │ ├── d_shuijiao.png
│ │ ├── d_sikao.png
│ │ ├── d_taikaixin.png
│ │ ├── d_touxiao.png
│ │ ├── d_travel.png
│ │ ├── d_tu.png
│ │ ├── d_tuzi.png
│ │ ├── d_wabishi.png
│ │ ├── d_weiqu.png
│ │ ├── d_xiaoku.png
│ │ ├── d_xiongmao.png
│ │ ├── d_xixi.png
│ │ ├── d_xu.png
│ │ ├── d_yinxian.png
│ │ ├── d_yiwen.png
│ │ ├── d_youhengheng.png
│ │ ├── d_yun.png
│ │ ├── d_zhuakuang.png
│ │ ├── d_zhutou.png
│ │ ├── d_zuiyou.png
│ │ ├── d_zuohengheng.png
│ │ ├── file_load_fail.png
│ │ ├── gxu.png
│ │ ├── gxv.png
│ │ ├── gxw.png
│ │ ├── gxx.png
│ │ ├── gxy.png
│ │ ├── gxz.png
│ │ ├── icon_chat_image.png
│ │ ├── icon_chat_take_photo.png
│ │ ├── loading1.png
│ │ ├── loading2.png
│ │ └── loading3.png
│ │ ├── drawable
│ │ ├── anim_chat_voice_left.xml
│ │ ├── anim_chat_voice_right.xml
│ │ ├── bg_chat_time_tag.xml
│ │ ├── chat_file_content_loading_anim.xml
│ │ ├── chat_from_bg_selector.xml
│ │ ├── chat_to_bg_selector.xml
│ │ ├── ic_keyboard_emotion.xml
│ │ ├── ic_keyboard_more.xml
│ │ ├── ic_keyboard_voice.xml
│ │ ├── ic_tabbar_contact.xml
│ │ ├── ic_tabbar_message.xml
│ │ ├── ic_toolbar_add.xml
│ │ ├── ic_toolbar_avatar.xml
│ │ ├── keyboard_emotion_indicator_nomal_bg.xml
│ │ ├── keyboard_emotion_indicator_select_bg.xml
│ │ ├── keyboard_input_edittext_bg.xml
│ │ ├── keyboard_record_voice_button_bg.xml
│ │ ├── main_bg.xml
│ │ ├── main_button_bg.xml
│ │ ├── recording_vocie_view_bg.xml
│ │ ├── recording_voice_cancel_text_bg.xml
│ │ ├── tigerframe_icon_back_btn_selector.xml
│ │ ├── vector_about.xml
│ │ ├── vector_add.xml
│ │ ├── vector_add_focus.xml
│ │ ├── vector_avatar.xml
│ │ ├── vector_avatar_focus.xml
│ │ ├── vector_chat_avatar.xml
│ │ ├── vector_checked.xml
│ │ ├── vector_contact.xml
│ │ ├── vector_contact_focus.xml
│ │ ├── vector_contact_group.xml
│ │ ├── vector_default_image.xml
│ │ ├── vector_emotion_more.xml
│ │ ├── vector_keyboard_emotion.xml
│ │ ├── vector_keyboard_emotion_delete.xml
│ │ ├── vector_keyboard_emotion_focus.xml
│ │ ├── vector_keyboard_more.xml
│ │ ├── vector_keyboard_more_focus.xml
│ │ ├── vector_keyboard_normal.xml
│ │ ├── vector_keyboard_pressed.xml
│ │ ├── vector_keyboard_text.xml
│ │ ├── vector_keyboard_text_focus.xml
│ │ ├── vector_keyboard_voice.xml
│ │ ├── vector_keyboard_voice_focus.xml
│ │ ├── vector_message.xml
│ │ ├── vector_message_focus.xml
│ │ ├── vector_multi_chat.xml
│ │ ├── vector_recording_cancel.xml
│ │ ├── vector_recording_voice.xml
│ │ ├── vector_share.xml
│ │ └── vector_uncheck.xml
│ │ ├── layout
│ │ ├── activity_about.xml
│ │ ├── activity_account_mng_layout.xml
│ │ ├── activity_addfriend_layout.xml
│ │ ├── activity_chat_layout.xml
│ │ ├── activity_create_multi_chat.xml
│ │ ├── activity_login_layout.xml
│ │ ├── activity_main.xml
│ │ ├── activity_main_bar.xml
│ │ ├── activity_main_content.xml
│ │ ├── activity_main_nav_header.xml
│ │ ├── activity_multichat_layout.xml
│ │ ├── activity_register_layout.xml
│ │ ├── activity_webpage.xml
│ │ ├── chat_keyboard_emotion_layout.xml
│ │ ├── chat_keyboard_emotion_tab_item_layout.xml
│ │ ├── chat_keyboard_layout.xml
│ │ ├── chat_keyboard_more_item_layout.xml
│ │ ├── chat_keyboard_more_layout.xml
│ │ ├── chat_keyboard_toolbox_layout.xml
│ │ ├── chat_messgae_item_left_layout.xml
│ │ ├── chat_messgae_item_right_layout.xml
│ │ ├── chat_record_item_layout.xml
│ │ ├── checkable_contact_item_view.xml
│ │ ├── contact_item_index_view.xml
│ │ ├── contact_item_view.xml
│ │ ├── divider_horizontal_view.xml
│ │ ├── fragment_contact.xml
│ │ ├── fragment_emotion_layout.xml
│ │ ├── fragment_message.xml
│ │ ├── keyboard_recording_voice_layout.xml
│ │ ├── tabbar_item_view.xml
│ │ └── toolbar_layout.xml
│ │ ├── menu
│ │ ├── activity_main_drawer.xml
│ │ ├── create_multi_chat_toolbar_menu.xml
│ │ └── main_toolbar_menu.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ └── values
│ │ ├── arrays.xml
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── cn
│ └── ittiger
│ └── im
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── projectFilesBackup
└── .idea
│ └── workspace.xml
├── screenshots
├── 1.jpg
├── 2.jpg
└── 3.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TigerIM
2 | 基于Openfire+Smack实现的简单即时通信客户端,界面仿照QQ实现。
3 | 实现了简单的登陆、注册、点对点聊天,发送文本、语音、图片消息,同时程序中实现了多人之间的聊天,但是没写界面,后面有时间之后再完善吧。
4 | 目前程序完全可以独立运行,程序里面配置了服务器。
5 |
6 | Smack与openfire服务之间的通信关键代码和实现可以参考我的[博客文章](http://ittiger.cn/tags/smack/)
7 |
8 | 此Demo已停止维护
9 |
10 | 个人微信公众号,欢迎扫码关注交流:
11 | 
12 |
13 | # 实现效果如如下:
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/TigerLibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/TigerLibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion "24.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 14
9 | targetSdkVersion 24
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile 'com.android.support:appcompat-v7:24.2.1'
23 | }
24 |
--------------------------------------------------------------------------------
/TigerLibrary/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/baina/ylhu/program/android-sdk-linux/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/app/AppContext.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.app;
2 |
3 | import android.content.Context;
4 | import android.content.ContextWrapper;
5 | import android.content.pm.PackageManager.NameNotFoundException;
6 |
7 | public class AppContext extends ContextWrapper {
8 |
9 | private static AppContext sInstance;
10 |
11 | public static void init(Context context) {
12 |
13 | if (sInstance == null) {
14 | try {
15 | sInstance = new AppContext(context.createPackageContext(context.getPackageName(),
16 | Context.CONTEXT_INCLUDE_CODE));
17 | } catch (NameNotFoundException e) {
18 | throw new RuntimeException(e);
19 | }
20 | }
21 | }
22 |
23 | public static AppContext getInstance() {
24 |
25 | return sInstance;
26 | }
27 |
28 | private AppContext(Context context) {
29 |
30 | super(context);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/base/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.base;
2 |
3 | import cn.ittiger.R;
4 | import cn.ittiger.util.PageLoadingHelper;
5 |
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.content.Context;
8 | import android.os.Bundle;
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 | /**
16 | * @author laohu
17 | * @site http://ittiger.cn
18 | */
19 | public abstract class BaseFragment extends Fragment {
20 |
21 | protected AppCompatActivity mContext;
22 | private PageLoadingHelper mPageLoadingHelper;
23 |
24 | @Override
25 | public void onAttach(Context context) {
26 |
27 | super.onAttach(context);
28 | mContext = (AppCompatActivity) context;
29 | }
30 |
31 | @Nullable
32 | @Override
33 | public final View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
34 |
35 | ViewGroup view = (ViewGroup) inflater.inflate(R.layout.base_layout, container, false);
36 |
37 | view.addView(getContentView(inflater, savedInstanceState), 0);
38 |
39 | mPageLoadingHelper = new PageLoadingHelper(view);
40 | mPageLoadingHelper.setOnLoadingClickListener(new View.OnClickListener() {
41 |
42 | @Override
43 | public void onClick(View v) {
44 |
45 | clickToRefresh();
46 | }
47 | });
48 | clickToRefresh();
49 |
50 | return view;
51 | }
52 |
53 | /**
54 | * 点击刷新加载
55 | */
56 | private void clickToRefresh() {
57 |
58 | startRefresh();
59 | refreshData();
60 | }
61 |
62 | /**
63 | * 初始化数据
64 | * 主线程
65 | */
66 | public abstract void refreshData();
67 |
68 | /**
69 | * 开始加载数据
70 | */
71 | public void startRefresh() {
72 |
73 | mPageLoadingHelper.startRefresh();
74 | }
75 |
76 | /**
77 | * 加载失败
78 | */
79 | public void refreshFailed() {
80 |
81 | mPageLoadingHelper.refreshFailed();
82 | }
83 |
84 | /**
85 | * 加载成功
86 | */
87 | public void refreshSuccess() {
88 |
89 | mPageLoadingHelper.refreshSuccess();
90 | }
91 |
92 | /**
93 | * Fragment数据视图
94 | * @param inflater
95 | * @param savedInstanceState
96 | * @return
97 | */
98 | public abstract View getContentView(LayoutInflater inflater, @Nullable Bundle savedInstanceState);
99 |
100 | public abstract String getTitle();
101 | }
102 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/ui/NoHorizontalScrollViewPager.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.ui;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.ViewPager;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 |
8 | /**
9 | * 不能横向滑动的ViewPager
10 | *
11 | * @author: laohu on 2017/2/6
12 | * @site: http://ittiger.cn
13 | */
14 | public class NoHorizontalScrollViewPager extends ViewPager {
15 |
16 | public NoHorizontalScrollViewPager(Context context) {
17 | super(context);
18 | }
19 |
20 | public NoHorizontalScrollViewPager(Context context, AttributeSet attrs) {
21 | super(context, attrs);
22 | }
23 |
24 | /**
25 | * 重写拦截事件,返回值设置为false,这时便不会横向滑动了。
26 | * @param ev
27 | * @return
28 | */
29 | @Override
30 | public boolean onInterceptTouchEvent(MotionEvent ev) {
31 |
32 | return false;
33 | }
34 |
35 | /**
36 | * 重写拦截事件,返回值设置为false,这时便不会横向滑动了。
37 | * @param ev
38 | * @return
39 | */
40 | @Override
41 | public boolean onTouchEvent(MotionEvent ev) {
42 |
43 | return false;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/ActivityUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 |
8 | /**
9 | * Created by laohu on 16-12-14.
10 | */
11 | public class ActivityUtil {
12 |
13 | public static void startActivity(Context context, Intent intent) {
14 |
15 | context.startActivity(intent);
16 | }
17 |
18 | public static void startActivity(Context context, Class claxx) {
19 |
20 | startActivity(context, new Intent(context, claxx));
21 | }
22 |
23 | public static void startActivity(Context context, Class claxx, Bundle bundle) {
24 |
25 | Intent intent = new Intent(context, claxx);
26 | intent.putExtras(bundle);
27 | startActivity(context, intent);
28 | }
29 |
30 | public static void skipActivity(Context context, Class claxx) {
31 |
32 | startActivity(context, claxx);
33 | finishActivity((Activity) context);
34 | }
35 |
36 | public static void finishActivity(Activity activity) {
37 |
38 | activity.finish();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/AppInfo.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import android.graphics.drawable.Drawable;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * 系统内安装的应用信息
9 | * @auther: hyl
10 | * @time: 2015-10-26上午9:51:32
11 | */
12 | public class AppInfo implements Serializable {
13 | /**
14 | *
15 | */
16 | private static final long serialVersionUID = 1L;
17 |
18 | /**
19 | * 应用名称
20 | */
21 | private String mAppLable;
22 | /**
23 | * 应用图标
24 | */
25 | private Drawable mAppIcon;
26 | /**
27 | * 应用包名
28 | */
29 | private String mAppPackage;
30 | /**
31 | * 应用class
32 | */
33 | private String mAppClass;
34 |
35 | public String getAppLable() {
36 | return mAppLable;
37 | }
38 | public void setAppLable(String appLable) {
39 | this.mAppLable = appLable;
40 | }
41 | public Drawable getAppIcon() {
42 | return mAppIcon;
43 | }
44 | public void setAppIcon(Drawable appIcon) {
45 | this.mAppIcon = appIcon;
46 | }
47 | public String getAppPackage() {
48 | return mAppPackage;
49 | }
50 | public void setAppPackage(String appPackage) {
51 | this.mAppPackage = appPackage;
52 | }
53 | public String getAppClass() {
54 | return mAppClass;
55 | }
56 | public void setAppClass(String appClass) {
57 | this.mAppClass = appClass;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/BitmapUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 |
6 | import java.io.File;
7 | import java.io.FileOutputStream;
8 |
9 | public class BitmapUtil {
10 | /**
11 | * 获取缩放图
12 | * @param file
13 | * @param width
14 | * @return
15 | */
16 | public static Bitmap createBitmapWithFile(String filePath, int width) {
17 | BitmapFactory.Options options = new BitmapFactory.Options();
18 | options.inJustDecodeBounds = true;
19 | BitmapFactory.decodeFile(filePath, options);
20 | options.inSampleSize = options.outWidth / width;
21 | if(options.outWidth == 0) {
22 | //避免图片还没有保存成功
23 | options.outWidth = width;
24 | options.outHeight = width * 4 / 3;
25 | }else {
26 | options.outHeight = options.outHeight * width / options.outWidth;
27 | options.outWidth = width;
28 | }
29 | options.inDither = false; //图片不抖动
30 | options.inJustDecodeBounds = false;
31 | options.inPreferredConfig = Bitmap.Config.ARGB_4444;
32 | options.inPurgeable = true;
33 | options.inInputShareable = true;
34 | Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
35 | return bitmap;
36 | }
37 |
38 | /***
39 | * 通过bitmap获取图片
40 | * @param filePath
41 | * @param bitmap
42 | */
43 | public static void createPictureWithBitmap(String filePath, Bitmap bitmap) {
44 | File file = new File(filePath);
45 | if(file.exists()) {
46 | file.delete();
47 | }
48 | try {
49 | FileOutputStream outputStream = new FileOutputStream(file);
50 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
51 | outputStream.flush();
52 | outputStream.close();
53 | } catch (Exception e) {
54 | }
55 | }
56 |
57 | /**
58 | * 通过bitmap获取图片
59 | * @param filePath
60 | * @param bitmap
61 | * @param percent 获取图片质量
62 | */
63 | public static void createPictureWithBitmap(String filePath, Bitmap bitmap, int percent) {
64 | File file = new File(filePath);
65 | if(file.exists()) {
66 | file.delete();
67 | }
68 | try {
69 | FileOutputStream outputStream = new FileOutputStream(file);
70 | bitmap.compress(Bitmap.CompressFormat.JPEG, percent, outputStream);
71 | outputStream.flush();
72 | outputStream.close();
73 | } catch (Exception e) {
74 | }
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/ByteUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.ObjectInputStream;
6 | import java.io.ObjectOutputStream;
7 |
8 | public class ByteUtil {
9 | /**
10 | * byte[] 转为 对象
11 | *
12 | * @param bytes
13 | * @return
14 | */
15 | public static Object byteToObject(byte[] bytes) throws Exception {
16 | ObjectInputStream ois = null;
17 | try {
18 | ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
19 | return ois.readObject();
20 | } finally {
21 | if (ois != null) ois.close();
22 | }
23 | }
24 |
25 | /**
26 | * 对象 转为 byte[]
27 | *
28 | * @param obj
29 | * @return
30 | */
31 | public static byte[] objectToByte(Object obj) throws Exception {
32 | ObjectOutputStream oos = null;
33 | try {
34 | ByteArrayOutputStream bos = new ByteArrayOutputStream();
35 | oos = new ObjectOutputStream(bos);
36 | oos.writeObject(obj);
37 | return bos.toByteArray();
38 | } finally {
39 | if (oos != null) oos.close();
40 | }
41 | }
42 |
43 | public static void byteToBit(byte[] bytes, StringBuilder sb) {
44 | for (int i = 0; i < Byte.SIZE * bytes.length; i++)
45 | sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
46 | }
47 |
48 | public static String byteToBit(byte[] bytes) {
49 | StringBuilder sb = new StringBuilder();
50 | for (int i = 0; i < Byte.SIZE * bytes.length; i++)
51 | sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
52 | return sb.toString();
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/DisplayUtils.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.util.DisplayMetrics;
6 |
7 | public class DisplayUtils {
8 | /**
9 | * 将px值转换为dp值
10 | */
11 | public static int px2dp(Context context, float pxValue) {
12 | final float scale = context.getResources().getDisplayMetrics().density;
13 | return (int) (pxValue / scale + 0.5f);
14 | }
15 |
16 | /**
17 | * 将dp值转换为px值
18 | */
19 | public static int dp2px(Context context, float dpValue) {
20 | final float scale = context.getResources().getDisplayMetrics().density;
21 | return (int) (dpValue * scale + 0.5f);
22 | }
23 |
24 | /**
25 | * 将px值转换为sp值
26 | */
27 | public static int px2sp(Context context, float pxValue) {
28 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
29 | return (int) (pxValue / fontScale + 0.5f);
30 | }
31 |
32 | /**
33 | * 将sp值转换为px值
34 | */
35 | public static int sp2px(Context context, float spValue) {
36 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
37 | return (int) (spValue * fontScale + 0.5f);
38 | }
39 |
40 | /**
41 | * 获取屏幕宽度
42 | */
43 | public static int getScreenWidthPixels(Activity context) {
44 | DisplayMetrics metric = new DisplayMetrics();
45 | context.getWindowManager().getDefaultDisplay().getMetrics(metric);
46 | return metric.widthPixels;
47 | }
48 |
49 | /**
50 | * 获取屏幕高度
51 | */
52 | public static int getScreenHeightPixels(Activity context) {
53 | DisplayMetrics metric = new DisplayMetrics();
54 | context.getWindowManager().getDefaultDisplay().getMetrics(metric);
55 | return metric.heightPixels;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/KeyboardUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.view.inputmethod.InputMethodManager;
6 |
7 | /**
8 | * @author: laohu on 2017/2/5
9 | * @site: http://ittiger.cn
10 | */
11 | public class KeyboardUtil {
12 |
13 | /**
14 | * 隐藏软键盘
15 | */
16 | public static void hideKeyboard(Context context) {
17 |
18 | Activity activity = (Activity) context;
19 | if (activity != null) {
20 | InputMethodManager imm = (InputMethodManager) activity
21 | .getSystemService(Context.INPUT_METHOD_SERVICE);
22 | if (imm.isActive() && activity.getCurrentFocus() != null) {
23 | imm.hideSoftInputFromWindow(activity.getCurrentFocus()
24 | .getWindowToken(), 0);
25 | }
26 | }
27 | }
28 |
29 | /**
30 | * 显示软键盘
31 | */
32 | public static void showKeyboard(Context context) {
33 |
34 | Activity activity = (Activity) context;
35 | if (activity != null) {
36 | InputMethodManager imm = (InputMethodManager) activity
37 | .getSystemService(Context.INPUT_METHOD_SERVICE);
38 | imm.showSoftInputFromInputMethod(activity.getCurrentFocus()
39 | .getWindowToken(), 0);
40 | imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/PageLoadingHelper.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import cn.ittiger.R;
4 | import cn.ittiger.ui.LoadingView;
5 |
6 | import android.view.View;
7 | import android.widget.FrameLayout;
8 | import android.widget.TextView;
9 |
10 | /**
11 | * 页面加载的时候,页面加载进度条及加载失败后的处理
12 | * @author: laohu on 2016/7/3
13 | * @site: http://ittiger.cn
14 | */
15 | public class PageLoadingHelper {
16 | private FrameLayout mLoadingFailedLayout;
17 | private LoadingView mLoadingView;
18 | private TextView mLoadingFailedText;
19 |
20 | public PageLoadingHelper(View rootView) {
21 |
22 | mLoadingFailedLayout = (FrameLayout) rootView.findViewById(R.id.loading_failed_layout);
23 | mLoadingView = (LoadingView) rootView.findViewById(R.id.loadingView);
24 | mLoadingFailedText = (TextView) rootView.findViewById(R.id.errorView);
25 | }
26 |
27 | public void setOnLoadingClickListener(final View.OnClickListener onClickListener) {
28 |
29 | this.mLoadingFailedText.setOnClickListener(new View.OnClickListener() {
30 |
31 | @Override
32 | public void onClick(View v) {
33 |
34 | if(onClickListener != null) {
35 | mLoadingFailedText.setVisibility(View.GONE);
36 | onClickListener.onClick(v);
37 | }
38 | }
39 | });
40 | }
41 |
42 | public void setLoadingFailedText(String failedText) {
43 |
44 | mLoadingFailedText.setText(failedText);
45 | }
46 |
47 | /**
48 | * 开始加载数据
49 | */
50 | public void startRefresh() {
51 |
52 | if(mLoadingView.getVisibility() == View.GONE) {
53 | mLoadingFailedLayout.setVisibility(View.VISIBLE);
54 | mLoadingView.setVisibility(View.VISIBLE);
55 | mLoadingView.start();
56 | mLoadingFailedText.setVisibility(View.GONE);
57 | }
58 | }
59 |
60 | /**
61 | * 加载失败
62 | */
63 | public void refreshFailed() {
64 |
65 | if(mLoadingView.getVisibility() == View.VISIBLE) {
66 | mLoadingView.stop();
67 | mLoadingView.setVisibility(View.GONE);
68 | mLoadingFailedText.setVisibility(View.VISIBLE);
69 | }
70 | }
71 |
72 | /**
73 | * 加载成功
74 | */
75 | public void refreshSuccess() {
76 |
77 | if(mLoadingFailedLayout.getVisibility() == View.VISIBLE) {
78 | mLoadingView.stop();
79 | mLoadingFailedLayout.setVisibility(View.GONE);
80 | mLoadingView.setVisibility(View.GONE);
81 | mLoadingFailedText.setVisibility(View.GONE);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/SdCardUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.os.Environment;
7 | import android.os.StatFs;
8 |
9 | import java.io.File;
10 |
11 | /**
12 | * SDCard帮助类
13 | * @author: huylee
14 | * @time: 2015-8-13下午10:13:31
15 | */
16 | public class SdCardUtil {
17 |
18 | /**
19 | * 是否存在SD卡
20 | * @return
21 | */
22 | public static boolean isHasSDCard() {
23 | return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
24 | }
25 |
26 | /**
27 | * 获取手机SD卡根目录路径
28 | * @return
29 | */
30 | public static String getSDCardDir() {
31 | return Environment.getExternalStorageDirectory().getPath();
32 | }
33 |
34 | /**
35 | * 获取手机自身根目录
36 | * @return
37 | */
38 | public static String getMobileDir() {
39 | return Environment.getDataDirectory().getAbsolutePath();
40 | }
41 |
42 | /**
43 | * 获取手机数据根目录,有Sdcard则返回Sdcard根目录,没有则返回手机自身根目录
44 | * @return
45 | */
46 | public static String getRootPath() {
47 | return isHasSDCard() ? getSDCardDir() : getMobileDir();
48 | }
49 |
50 | /**
51 | * 应用缓存目录,可以通过手机中的清除缓存把数据清除掉
52 | * @param context
53 | * @return
54 | */
55 | public static String getCacheDir(Context context) {
56 | return context.getCacheDir().getAbsolutePath();
57 | }
58 |
59 | /**
60 | * 获取当前应用的文件目录
61 | * @param context
62 | * @return
63 | */
64 | public static String getFilesDir(Context context) {
65 | return context.getFilesDir().getAbsolutePath();
66 | }
67 |
68 | /**
69 | * 获取当前路径,可用空间
70 | */
71 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
72 | public static long getAvailableSize(String path) {
73 | try {
74 | File base = new File(path);
75 | StatFs stat = new StatFs(base.getPath());
76 | return stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
77 | } catch (Exception e) {
78 | e.printStackTrace();
79 | }
80 | return 0;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/UIUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import android.content.Context;
4 | import android.os.Handler;
5 | import android.os.Looper;
6 | import android.widget.Toast;
7 |
8 | /**
9 | * Created by laohu on 16-12-14.
10 | */
11 | public class UIUtil {
12 |
13 | private static Handler sHandler = new Handler(Looper.getMainLooper());
14 |
15 | public static Thread getUIThread() {
16 |
17 | return Looper.getMainLooper().getThread();
18 | }
19 |
20 | public static boolean isOnUIThread() {
21 |
22 | return Thread.currentThread() == getUIThread();
23 | }
24 |
25 | /**
26 | * 在UI线程执行
27 | *
28 | * @param action
29 | */
30 | public static void runOnUIThread(Runnable action) {
31 |
32 | if (!isOnUIThread()) {
33 | getHandler().post(action);
34 | } else {
35 | action.run();
36 | }
37 | }
38 |
39 | public static Handler getHandler() {
40 |
41 | return sHandler;
42 | }
43 |
44 | public static void showToast(Context context, String msg) {
45 |
46 | Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
47 | }
48 |
49 | public static void showToast(Context context, int resId) {
50 |
51 | Toast.makeText(context, context.getString(resId), Toast.LENGTH_SHORT).show();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/ValueUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util;
2 |
3 | import java.util.Collection;
4 |
5 | public class ValueUtil {
6 | /**
7 | * 判断字符串是否为空,Null或空白字符串均返回true
8 | * Author: hyl
9 | * Time: 2015-8-13下午1:18:26
10 | * @param value
11 | * @return
12 | */
13 | public static boolean isEmpty(String value) {
14 | if(value == null) {
15 | return true;
16 | }
17 | if(value.trim().length() == 0) {
18 | return true;
19 | }
20 | return false;
21 | }
22 |
23 | /**
24 | * 判断集合是否为空,Null或集合没有元素均返回true
25 | * Author: hyl
26 | * Time: 2015-8-17下午9:30:24
27 | * @param collection
28 | * @return
29 | */
30 | public static boolean isEmpty(Collection> collection) {
31 | if(collection == null || collection.size() <= 0) {
32 | return true;
33 | }
34 | return false;
35 | }
36 |
37 | /**
38 | * 判断Object是否为空
39 | * Author: hyl
40 | * Time: 2015-8-17下午9:42:29
41 | * @param object
42 | * @return
43 | */
44 | public static boolean isEmpty(Object object) {
45 | if(object == null) {
46 | return true;
47 | }
48 | return false;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/cipher/Base64Cipher.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util.cipher;
2 |
3 | import android.util.Base64;
4 |
5 | public class Base64Cipher extends Cipher {
6 | private Cipher cipher;
7 |
8 | public Base64Cipher() {
9 | }
10 |
11 | public Base64Cipher(Cipher cipher) {
12 | this.cipher = cipher;
13 | }
14 |
15 | @Override
16 | public byte[] decrypt(byte[] res) {
17 | if(cipher != null) res = cipher.decrypt(res);
18 | return Base64.decode(res, Base64.DEFAULT);
19 | }
20 |
21 | @Override
22 | public byte[] encrypt(byte[] res) {
23 | if(cipher != null) res = cipher.encrypt(res);
24 | return Base64.encode(res, Base64.DEFAULT);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/cipher/Cipher.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util.cipher;
2 |
3 | /**
4 | * @author MaTianyu
5 | * @date 14-7-31
6 | */
7 | public abstract class Cipher implements Encrypt,Decrypt{
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/cipher/Decrypt.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util.cipher;
2 |
3 | /**
4 | * @author MaTianyu
5 | * @date 14-7-31
6 | */
7 | public interface Decrypt {
8 | public byte[] decrypt(byte[] res);
9 | }
10 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/java/cn/ittiger/util/cipher/Encrypt.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.util.cipher;
2 |
3 | /**
4 | * @author MaTianyu
5 | * @date 14-7-31
6 | */
7 | public interface Encrypt {
8 | public byte[] encrypt(byte[] res);
9 | }
10 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/res/layout/base_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/res/layout/loading_failed_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
20 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/TigerLibrary/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 加载失败,点击重试
3 | 再按一次退出程序
4 |
5 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | //butterknife
3 | apply plugin: 'android-apt'
4 |
5 | android {
6 | compileSdkVersion 24
7 | buildToolsVersion "24.0.2"
8 |
9 | defaultConfig {
10 | applicationId "cn.ittiger.im"
11 | minSdkVersion 14
12 | targetSdkVersion 24
13 | versionCode 2
14 | versionName "2.0"
15 | vectorDrawables.useSupportLibrary=true
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | compile fileTree(dir: 'libs', include: ['*.jar'])
27 | testCompile 'junit:junit:4.12'
28 | compile project(':TigerLibrary')
29 | compile 'com.android.support:design:24.2.1'
30 | compile 'com.android.support:cardview-v7:24.2.1'
31 | compile 'cn.ittiger:indexstickyview:1.1.0'
32 |
33 | //smack-core为核心库
34 | compile 'org.igniterealtime.smack:smack-core:4.1.9'
35 | //Smack IM.Classes and methods for XMPP-IM (RFC 6121): Roster, Chat and other functionality
36 | compile "org.igniterealtime.smack:smack-im:4.1.9"
37 | //Smack for Android. All the required dependencies to run Smack on Android.
38 | //smack-android依赖smack-extensions和smack-experimental和smack-tcp
39 | compile "org.igniterealtime.smack:smack-android:4.1.9"
40 | compile "org.igniterealtime.smack:smack-android-extensions:4.1.9"
41 | //XMPP connections
42 | compile "org.igniterealtime.smack:smack-tcp:4.1.9"
43 | //support for the various XMPP XEPs (Multi-User Chat, PubSub, …) and other XMPP extensions.
44 | compile "org.igniterealtime.smack:smack-extensions:4.1.9"
45 | compile "org.igniterealtime.smack:smack-experimental:4.1.9"
46 |
47 | //UIL
48 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
49 | //Logger
50 | compile 'com.orhanobut:logger:1.15'
51 |
52 | //butterknife
53 | compile 'com.jakewharton:butterknife:8.4.0'
54 | apt 'com.jakewharton:butterknife-compiler:8.4.0'
55 |
56 | //rxjava
57 | compile 'io.reactivex:rxjava:1.1.6'
58 | compile 'io.reactivex:rxandroid:1.2.1'
59 |
60 | //eventbus
61 | compile 'org.greenrobot:eventbus:3.0.0'
62 | }
63 |
--------------------------------------------------------------------------------
/app/libs/TigerDB.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/libs/TigerDB.jar
--------------------------------------------------------------------------------
/app/problem.md:
--------------------------------------------------------------------------------
1 | ### java.lang.VerifyError: org/jivesoftware/smack/sasl/javax/SASLJavaXMechanism
2 | 在初始化`XMPPTCPConnectionConfiguration.builder()`的时候出现上述异常,移除smack-java7相关jar包即可
3 |
4 | ### org.jivesoftware.smack.smackexception$noresponseexception no response received within reply timeout
5 | 登陆的时候出现这个异常信息,一直以为是代码出现了问题,然后各种google,结果依然无效,最后发现将手机的网络代理去掉就ok了,我擦嘞~~~
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/baina/ylhu/program/android-sdk-linux/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/cn/ittiger/im/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 |
12 | super(Application.class);
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
34 |
35 |
38 |
39 |
42 |
43 |
47 |
48 |
51 |
52 |
55 |
56 |
59 |
60 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/activity/AccountMngActivity.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.activity;
2 |
3 | import android.os.Bundle;
4 | import android.view.View;
5 | import android.widget.Button;
6 | import android.widget.RadioGroup;
7 | import android.widget.RadioGroup.OnCheckedChangeListener;
8 |
9 | import butterknife.BindView;
10 | import butterknife.OnClick;
11 | import cn.ittiger.base.BaseActivity;
12 | import cn.ittiger.im.R;
13 | import cn.ittiger.im.smack.SmackManager;
14 | import cn.ittiger.util.ActivityUtil;
15 | import cn.ittiger.util.UIUtil;
16 |
17 | /**
18 | * 账号管理
19 | * @auther: hyl
20 | * @time: 2015-10-23下午3:11:11
21 | */
22 | public class AccountMngActivity extends BaseActivity {
23 | /**
24 | * 注销登陆
25 | */
26 | @BindView(R.id.btn_logout)
27 | Button mBtnLogout;
28 | /**
29 | * 用户状态修改
30 | */
31 | @BindView(R.id.rg_user_state)
32 | RadioGroup mUserState;
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_account_mng_layout);
38 |
39 | mUserState.setOnCheckedChangeListener(new OnCheckedChangeListener() {
40 | @Override
41 | public void onCheckedChanged(RadioGroup group, int checkedId) {
42 | switch(checkedId) {
43 | case R.id.rb_user_online://在线
44 | changeState(0);
45 | break;
46 | case R.id.rb_user_busy://忙碌
47 | changeState(2);
48 | break;
49 | case R.id.rb_disconnect://断开连接
50 | disconnect();
51 | break;
52 | }
53 | }
54 | });
55 | }
56 |
57 | public void changeState(int code) {
58 | if(SmackManager.getInstance().updateUserState(code)) {
59 | UIUtil.showToast(this, "修改状态成功");
60 | } else {
61 | UIUtil.showToast(this, "修改状态失败");
62 | }
63 | }
64 |
65 | public void disconnect() {
66 | if(SmackManager.getInstance().disconnect()) {
67 | ActivityUtil.finishActivity(this);
68 | } else {
69 | UIUtil.showToast(this, "断开连接失败");
70 | }
71 | }
72 |
73 | /**
74 | * 注销登陆
75 | * @param v
76 | */
77 | @OnClick(R.id.btn_logout)
78 | public void onLogoutClick(View v) {
79 | if(SmackManager.getInstance().logout()) {
80 | ActivityUtil.finishActivity(this);
81 | } else {
82 | UIUtil.showToast(this, "注销失败");
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/activity/MultiChatActivity.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.activity;
2 |
3 | import org.greenrobot.eventbus.Subscribe;
4 | import org.greenrobot.eventbus.ThreadMode;
5 | import org.jivesoftware.smackx.muc.MultiUserChat;
6 | import org.json.JSONObject;
7 |
8 | import android.os.Bundle;
9 |
10 | import cn.ittiger.im.R;
11 | import cn.ittiger.im.activity.base.BaseChatActivity;
12 | import cn.ittiger.im.bean.ChatMessage;
13 | import cn.ittiger.im.constant.KeyBoardMoreFunType;
14 | import cn.ittiger.im.smack.SmackManager;
15 | import cn.ittiger.util.ValueUtil;
16 | import rx.Observable;
17 | import rx.functions.Action1;
18 | import rx.schedulers.Schedulers;
19 |
20 | import com.orhanobut.logger.Logger;
21 |
22 | import java.io.File;
23 |
24 | /**
25 | * 多人聊天
26 | *
27 | * @author: laohu on 2017/2/3
28 | * @site: http://ittiger.cn
29 | */
30 | public class MultiChatActivity extends BaseChatActivity {
31 | /**
32 | * 多人聊天对象
33 | */
34 | private MultiUserChat mMultiUserChat;
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 |
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.activity_multichat_layout);
41 | mMultiUserChat = SmackManager.getInstance().getMultiChat(mChatUser.getFriendUsername());
42 | }
43 |
44 | @Subscribe(threadMode = ThreadMode.MAIN)
45 | public void onReceiveChatMessageEvent(ChatMessage message) {
46 |
47 | if(mChatUser.getFriendUsername().equals(message.getFriendUsername()) && message.isMulti()) {
48 | addChatMessageView(message);
49 | }
50 | }
51 |
52 | @Override
53 | public void send(String message) {
54 |
55 | if (ValueUtil.isEmpty(message)) {
56 | return;
57 | }
58 | Observable.just(message)
59 | .observeOn(Schedulers.io())
60 | .subscribe(new Action1() {
61 | @Override
62 | public void call(String message) {
63 | try {
64 | JSONObject json = new JSONObject();
65 | json.put(ChatMessage.KEY_MESSAGE_CONTENT, message);
66 | json.put(ChatMessage.KEY_MULTI_CHAT_SEND_USER, mChatUser.getMeUsername());
67 | mMultiUserChat.sendMessage(json.toString());
68 | } catch (Exception e) {
69 | Logger.e(e, "send message failure");
70 | }
71 | }
72 | });
73 | }
74 |
75 | @Override
76 | public void sendVoice(File audioFile) {
77 |
78 | }
79 |
80 | @Override
81 | public void functionClick(KeyBoardMoreFunType funType) {
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/activity/base/IMBaseActivity.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.activity.base;
2 |
3 | import cn.ittiger.base.BaseActivity;
4 | import cn.ittiger.im.R;
5 |
6 | import android.os.Build;
7 | import android.os.Bundle;
8 |
9 | /**
10 | * @author: laohu on 2017/1/1
11 | * @site: http://ittiger.cn
12 | */
13 | public class IMBaseActivity extends BaseActivity {
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 |
18 | super.onCreate(savedInstanceState);
19 | initNavigationBarColor();
20 | }
21 |
22 | private void initNavigationBarColor() {
23 |
24 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
25 | getWindow().setNavigationBarColor(getResources().getColor(R.color.main_color));
26 | }
27 | }
28 |
29 | @Override
30 | public boolean isLceActivity() {
31 |
32 | return false;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/adapter/ChatRecordAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.adapter;
2 |
3 | import cn.ittiger.im.R;
4 | import cn.ittiger.im.adapter.viewholder.ChatRecordViewHolder;
5 | import cn.ittiger.im.bean.ChatRecord;
6 | import cn.ittiger.im.constant.EmotionType;
7 | import cn.ittiger.im.ui.recyclerview.HeaderAndFooterAdapter;
8 | import cn.ittiger.im.ui.recyclerview.ViewHolder;
9 | import cn.ittiger.im.util.ChatTimeUtil;
10 | import cn.ittiger.im.util.EmotionUtil;
11 | import cn.ittiger.im.util.ImageLoaderHelper;
12 | import cn.ittiger.util.ValueUtil;
13 |
14 | import android.content.Context;
15 | import android.text.SpannableString;
16 | import android.view.LayoutInflater;
17 | import android.view.View;
18 | import android.view.ViewGroup;
19 |
20 | import java.util.List;
21 |
22 | import static android.R.id.message;
23 |
24 | /**
25 | * 聊天记录列表适配器
26 | * @author: laohu on 2017/1/22
27 | * @site: http://ittiger.cn
28 | */
29 | public class ChatRecordAdapter extends HeaderAndFooterAdapter {
30 | private Context mContext;
31 |
32 | public ChatRecordAdapter(Context context, List list) {
33 |
34 | super(list);
35 | this.mContext = context;
36 | }
37 |
38 | @Override
39 | public ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
40 |
41 | View view = LayoutInflater.from(mContext).inflate(R.layout.chat_record_item_layout, parent, false);
42 | return new ChatRecordViewHolder(view);
43 | }
44 |
45 | @Override
46 | public void onBindItemViewHolder(ViewHolder holder, int position, ChatRecord item) {
47 |
48 | ChatRecordViewHolder viewHolder = (ChatRecordViewHolder) holder;
49 |
50 | if(!ValueUtil.isEmpty(item.getFriendAvatar())) {
51 | ImageLoaderHelper.displayImage(viewHolder.avatar, item.getFriendAvatar());
52 | }
53 | viewHolder.nickName.setText(item.getFriendNickname());
54 | if(!ValueUtil.isEmpty(item.getLastMessage())) {
55 | if(viewHolder.message.getVisibility() == View.GONE) {
56 | viewHolder.message.setVisibility(View.VISIBLE);
57 | }
58 | SpannableString content = EmotionUtil.getInputEmotionContent(mContext, EmotionType.EMOTION_TYPE_CLASSIC, viewHolder.message, item.getLastMessage());
59 | viewHolder.message.setText(content);
60 | }
61 | viewHolder.chatTime.setText(ChatTimeUtil.getFriendlyTimeSpanByNow(item.getChatTime()));
62 | String messageCount = item.getUnReadMessageCount() > 0 ? String.valueOf(item.getUnReadMessageCount()) : "";
63 | viewHolder.messageCount.setText(messageCount);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/adapter/CheckableContactAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.adapter;
2 |
3 | import cn.ittiger.im.R;
4 | import cn.ittiger.im.adapter.viewholder.ContactIndexViewHolder;
5 | import cn.ittiger.im.adapter.viewholder.CreateMultiChatViewHolder;
6 | import cn.ittiger.im.bean.CheckableContactEntity;
7 | import cn.ittiger.indexlist.adapter.IndexStickyViewAdapter;
8 |
9 | import android.content.Context;
10 | import android.support.v7.widget.RecyclerView;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * 可选联系人列表适配器
19 | * @author: laohu on 2017/1/24
20 | * @site: http://ittiger.cn
21 | */
22 | public class CheckableContactAdapter extends IndexStickyViewAdapter {
23 | private Context mContext;
24 |
25 | public CheckableContactAdapter(Context context, List originalList) {
26 |
27 | super(originalList);
28 | mContext = context;
29 | }
30 |
31 | @Override
32 | public RecyclerView.ViewHolder onCreateIndexViewHolder(ViewGroup parent) {
33 |
34 | View view = LayoutInflater.from(mContext).inflate(R.layout.contact_item_index_view, parent, false);
35 | return new ContactIndexViewHolder(view);
36 | }
37 |
38 | @Override
39 | public RecyclerView.ViewHolder onCreateContentViewHolder(ViewGroup parent) {
40 |
41 | View view = LayoutInflater.from(mContext).inflate(R.layout.checkable_contact_item_view, parent, false);
42 | return new CreateMultiChatViewHolder(view);
43 | }
44 |
45 | @Override
46 | public void onBindIndexViewHolder(RecyclerView.ViewHolder holder, int position, String indexName) {
47 |
48 | ContactIndexViewHolder viewHolder = (ContactIndexViewHolder) holder;
49 | viewHolder.getTextView().setText(indexName);
50 | }
51 |
52 | @Override
53 | public void onBindContentViewHolder(RecyclerView.ViewHolder holder, int position, CheckableContactEntity itemData) {
54 |
55 | CreateMultiChatViewHolder viewHolder = (CreateMultiChatViewHolder) holder;
56 | if(itemData.isChecked()) {
57 | viewHolder.getCheckImageView().setImageResource(R.drawable.vector_checked);
58 | } else {
59 | viewHolder.getCheckImageView().setImageResource(R.drawable.vector_uncheck);
60 | }
61 | viewHolder.getImageView().setImageResource(R.drawable.vector_contact_focus);
62 | viewHolder.getTextView().setText(itemData.getRosterEntry().getName());
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/adapter/ContactAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.adapter;
2 |
3 | import cn.ittiger.im.R;
4 | import cn.ittiger.im.adapter.viewholder.ContactIndexViewHolder;
5 | import cn.ittiger.im.adapter.viewholder.ContactViewHolder;
6 | import cn.ittiger.im.bean.ContactEntity;
7 | import cn.ittiger.indexlist.adapter.IndexStickyViewAdapter;
8 |
9 | import android.content.Context;
10 | import android.support.v7.widget.RecyclerView;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * 联系人列表数据适配器
19 | * @author: laohu on 2016/12/27
20 | * @site: http://ittiger.cn
21 | */
22 | public class ContactAdapter extends IndexStickyViewAdapter {
23 | private Context mContext;
24 | public ContactAdapter(Context context, List originalList) {
25 |
26 | super(originalList);
27 | mContext = context;
28 | }
29 |
30 | @Override
31 | public RecyclerView.ViewHolder onCreateIndexViewHolder(ViewGroup parent) {
32 |
33 | View view = LayoutInflater.from(mContext).inflate(R.layout.contact_item_index_view, parent, false);
34 | return new ContactIndexViewHolder(view);
35 | }
36 |
37 | @Override
38 | public RecyclerView.ViewHolder onCreateContentViewHolder(ViewGroup parent) {
39 |
40 | View view = LayoutInflater.from(mContext).inflate(R.layout.contact_item_view, parent, false);
41 | return new ContactViewHolder(view);
42 | }
43 |
44 | @Override
45 | public void onBindIndexViewHolder(RecyclerView.ViewHolder holder, int position, String indexName) {
46 |
47 | ContactIndexViewHolder viewHolder = (ContactIndexViewHolder) holder;
48 | viewHolder.getTextView().setText(indexName);
49 | }
50 |
51 | @Override
52 | public void onBindContentViewHolder(RecyclerView.ViewHolder holder, int position, ContactEntity itemData) {
53 |
54 | ContactViewHolder viewHolder = (ContactViewHolder) holder;
55 | viewHolder.getImageView().setImageResource(R.drawable.vector_contact_focus);
56 | viewHolder.getTextView().setText(itemData.getRosterEntry().getName());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/adapter/EmotionViewPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.adapter;
2 |
3 | import android.support.v4.view.PagerAdapter;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author: laohu on 2017/2/6
11 | * @site: http://ittiger.cn
12 | */
13 | public class EmotionViewPagerAdapter extends PagerAdapter {
14 | private List mViewList;
15 |
16 | public EmotionViewPagerAdapter(List viewList) {
17 |
18 | mViewList = viewList;
19 | }
20 |
21 | @Override
22 | public Object instantiateItem(ViewGroup container, int position) {
23 |
24 | View view = mViewList.get(position);
25 | container.addView(view);
26 | return view;
27 | }
28 |
29 | @Override
30 | public void destroyItem(ViewGroup container, int position, Object object) {
31 |
32 | container.removeView(mViewList.get(position));
33 | }
34 |
35 | @Override
36 | public int getCount() {
37 |
38 | return mViewList.size();
39 | }
40 |
41 | @Override
42 | public boolean isViewFromObject(View view, Object object) {
43 |
44 | return view == object;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/adapter/viewholder/ChatRecordViewHolder.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.adapter.viewholder;
2 |
3 | import butterknife.BindView;
4 | import butterknife.ButterKnife;
5 | import cn.ittiger.im.R;
6 | import cn.ittiger.im.ui.recyclerview.ViewHolder;
7 |
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | /**
13 | * @author: laohu on 2017/1/22
14 | * @site: http://ittiger.cn
15 | */
16 | public class ChatRecordViewHolder extends ViewHolder {
17 | @BindView(R.id.chat_friend_avatar)
18 | public ImageView avatar;
19 | @BindView(R.id.chat_friend_nickname)
20 | public TextView nickName;
21 | @BindView(R.id.chat_message)
22 | public TextView message;
23 | @BindView(R.id.chat_time)
24 | public TextView chatTime;
25 | @BindView(R.id.chat_message_count)
26 | public TextView messageCount;
27 |
28 | public ChatRecordViewHolder(View itemView) {
29 |
30 | super(itemView);
31 | ButterKnife.bind(this, itemView);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/adapter/viewholder/ContactIndexViewHolder.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.adapter.viewholder;
2 |
3 | import butterknife.BindView;
4 | import butterknife.ButterKnife;
5 | import cn.ittiger.im.R;
6 |
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.View;
9 | import android.widget.TextView;
10 |
11 | /**
12 | * Created by ylhu on 16-12-27.
13 | */
14 | public class ContactIndexViewHolder extends RecyclerView.ViewHolder {
15 | @BindView(R.id.contact_index_name)
16 | TextView mTextView;
17 |
18 | public ContactIndexViewHolder(View itemView) {
19 |
20 | super(itemView);
21 | ButterKnife.bind(this, itemView);
22 | }
23 |
24 | public TextView getTextView() {
25 |
26 | return mTextView;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/adapter/viewholder/ContactViewHolder.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.adapter.viewholder;
2 |
3 | import butterknife.BindView;
4 | import butterknife.ButterKnife;
5 | import cn.ittiger.im.R;
6 |
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | /**
13 | * 联系人列表Item项ViewHolder
14 | * @author: laohu on 2016/12/24
15 | * @site: http://ittiger.cn
16 | */
17 | public class ContactViewHolder extends RecyclerView.ViewHolder {
18 | @BindView(R.id.contact_avatar)
19 | ImageView avatar;
20 | @BindView(R.id.contact_name)
21 | TextView name;
22 |
23 | public ContactViewHolder(View itemView) {
24 |
25 | super(itemView);
26 | ButterKnife.bind(this, itemView);
27 | }
28 |
29 | public ImageView getImageView() {
30 |
31 | return avatar;
32 | }
33 |
34 | public TextView getTextView() {
35 |
36 | return name;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/adapter/viewholder/CreateMultiChatViewHolder.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.adapter.viewholder;
2 |
3 | import butterknife.BindView;
4 | import butterknife.ButterKnife;
5 | import cn.ittiger.im.R;
6 |
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | /**
13 | * @author: laohu on 2017/1/24
14 | * @site: http://ittiger.cn
15 | */
16 | public class CreateMultiChatViewHolder extends RecyclerView.ViewHolder {
17 | @BindView(R.id.contact_check)
18 | ImageView checkImageView;
19 | @BindView(R.id.contact_avatar)
20 | ImageView avatar;
21 | @BindView(R.id.contact_name)
22 | TextView name;
23 |
24 | public CreateMultiChatViewHolder(View itemView) {
25 |
26 | super(itemView);
27 | ButterKnife.bind(this, itemView);
28 | }
29 |
30 | public ImageView getCheckImageView() {
31 |
32 | return checkImageView;
33 | }
34 |
35 | public ImageView getImageView() {
36 |
37 | return avatar;
38 | }
39 |
40 | public TextView getTextView() {
41 |
42 | return name;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/app/IDbApplication.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.app;
2 |
3 | import cn.ittiger.database.SQLiteDBConfig;
4 |
5 | /**
6 | * 本地数据库接口
7 | * @author: laohu on 2017/1/18
8 | * @site: http://ittiger.cn
9 | */
10 | public interface IDbApplication {
11 | /**
12 | * 系统全局数据库配置
13 | * @return
14 | */
15 | SQLiteDBConfig getGlobalDbConfig();
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/bean/CheckableContactEntity.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.bean;
2 |
3 | import cn.ittiger.indexlist.entity.BaseEntity;
4 |
5 | import org.jivesoftware.smack.roster.RosterEntry;
6 |
7 | /**
8 | * 创建群聊时可选联系人实体
9 | * @author: laohu on 2017/1/24
10 | * @site: http://ittiger.cn
11 | */
12 | public class CheckableContactEntity implements BaseEntity {
13 | private RosterEntry mRosterEntry;
14 | private boolean mChecked = false;
15 |
16 | public CheckableContactEntity(RosterEntry rosterEntry) {
17 |
18 | mRosterEntry = rosterEntry;
19 | }
20 |
21 | @Override
22 | public String getIndexField() {
23 |
24 | return mRosterEntry.getName();
25 | }
26 |
27 | public RosterEntry getRosterEntry() {
28 |
29 | return mRosterEntry;
30 | }
31 |
32 | public boolean isChecked() {
33 |
34 | return mChecked;
35 | }
36 |
37 | public void setChecked(boolean checked) {
38 |
39 | mChecked = checked;
40 | }
41 |
42 | @Override
43 | public boolean equals(Object obj) {
44 |
45 | if(obj == null) {
46 | return false;
47 | }
48 | if(obj instanceof CheckableContactEntity) {
49 | return mRosterEntry.getUser().equals(((CheckableContactEntity) obj).getRosterEntry().getUser()) &&
50 | mRosterEntry.getName().equals(((CheckableContactEntity) obj).getRosterEntry().getName());
51 | }
52 |
53 | return false;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/bean/ContactEntity.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.bean;
2 |
3 | import cn.ittiger.indexlist.entity.BaseEntity;
4 |
5 | import org.jivesoftware.smack.roster.RosterEntry;
6 |
7 | /**
8 | * 联系人实体
9 | * @author: laohu on 2016/12/26
10 | * @site: http://ittiger.cn
11 | */
12 | public class ContactEntity implements BaseEntity {
13 | private RosterEntry mRosterEntry;
14 |
15 | public ContactEntity(RosterEntry rosterEntry) {
16 |
17 | mRosterEntry = rosterEntry;
18 | }
19 |
20 | @Override
21 | public String getIndexField() {
22 |
23 | return mRosterEntry.getName();
24 | }
25 |
26 | public RosterEntry getRosterEntry() {
27 |
28 | return mRosterEntry;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/bean/ContactMenuEntity.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.bean;
2 |
3 | import cn.ittiger.im.R;
4 | import cn.ittiger.indexlist.entity.BaseEntity;
5 |
6 | /**
7 | * 联系人列表头部的菜单项
8 | * @author: laohu on 2016/12/26
9 | * @site: http://ittiger.cn
10 | */
11 | public class ContactMenuEntity implements BaseEntity {
12 | private String mMenuName;
13 | private int mAvatar;
14 | private MenuType mMenuType;
15 |
16 | public ContactMenuEntity(String menuName, MenuType menuType) {
17 |
18 | mMenuName = menuName;
19 | mMenuType = menuType;
20 | mAvatar = menuType.getAvatar();
21 | }
22 |
23 | @Override
24 | public String getIndexField() {
25 |
26 | return mMenuName;
27 | }
28 |
29 | public String getMenuName() {
30 |
31 | return mMenuName;
32 | }
33 |
34 | public MenuType getMenuType() {
35 |
36 | return mMenuType;
37 | }
38 |
39 | public int getAvatar() {
40 |
41 | return mAvatar;
42 | }
43 |
44 | public enum MenuType {
45 | GROUP(R.drawable.vector_contact_group), //分组
46 | MULTI_CHAT(R.drawable.vector_multi_chat); //群聊
47 |
48 | private int mAvatar;
49 |
50 | MenuType(int avatar) {
51 |
52 | mAvatar = avatar;
53 | }
54 |
55 | public int getAvatar() {
56 |
57 | return mAvatar;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/bean/LoginResult.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.bean;
2 |
3 | /**
4 | * Created by ylhu on 16-12-14.
5 | */
6 | public class LoginResult {
7 |
8 | private User mUser;
9 | private boolean mSuccess;
10 | private String mErrorMsg;
11 |
12 | public LoginResult(User user, boolean success) {
13 |
14 | mUser = user;
15 | mSuccess = success;
16 | }
17 |
18 | public LoginResult(boolean success, String errorMsg) {
19 |
20 | mSuccess = success;
21 | mErrorMsg = errorMsg;
22 | }
23 |
24 | public boolean isSuccess() {
25 |
26 | return mSuccess;
27 | }
28 |
29 | public String getErrorMsg() {
30 |
31 | return mErrorMsg;
32 | }
33 |
34 | public User getUser() {
35 |
36 | return mUser;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/bean/MultiChatRoom.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.bean;
2 |
3 | import cn.ittiger.database.annotation.Column;
4 | import cn.ittiger.database.annotation.PrimaryKey;
5 | import cn.ittiger.database.annotation.Table;
6 |
7 | import org.jivesoftware.smackx.disco.packet.DiscoverItems;
8 |
9 | /**
10 | * 当前用户加入过的群聊
11 | *
12 | * @author: laohu on 2017/2/3
13 | * @site: http://ittiger.cn
14 | */
15 | @Table(name = "MultiChatRoom")
16 | public class MultiChatRoom {
17 | @PrimaryKey(isAutoGenerate = true)
18 | private long mId;
19 | @Column(columnName = "roomJid")
20 | private String mRoomJid;
21 |
22 | public MultiChatRoom() {
23 |
24 | }
25 |
26 | public MultiChatRoom(String roomJid) {
27 |
28 | mRoomJid = roomJid;
29 | }
30 |
31 | public String getRoomJid() {
32 |
33 | return mRoomJid;
34 | }
35 |
36 | public void setRoomJid(String roomJid) {
37 |
38 | mRoomJid = roomJid;
39 | }
40 |
41 | @Override
42 | public boolean equals(Object obj) {
43 |
44 | if(obj instanceof DiscoverItems.Item) {
45 | return ((DiscoverItems.Item) obj).getEntityID().equals(mRoomJid);
46 | }
47 | if(obj instanceof MultiChatRoom) {
48 | return ((MultiChatRoom) obj).mRoomJid.equals(mRoomJid);
49 | }
50 | return false;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/bean/User.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.bean;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by laohu on 16-12-14.
7 | */
8 | public class User implements Serializable {
9 |
10 | private String mUsername;
11 | private String mNickname;
12 | private String mPassword;
13 |
14 | public User() {
15 |
16 | }
17 |
18 | public User(String username, String password) {
19 |
20 | mUsername = username;
21 | mPassword = password;
22 | }
23 |
24 | public String getUsername() {
25 |
26 | return mUsername;
27 | }
28 |
29 | public void setUsername(String username) {
30 |
31 | mUsername = username;
32 | }
33 |
34 | public String getPassword() {
35 |
36 | return mPassword;
37 | }
38 |
39 | public void setPassword(String password) {
40 |
41 | mPassword = password;
42 | }
43 |
44 | public void setNickname(String nickname) {
45 |
46 | mNickname = nickname;
47 | }
48 |
49 | public String getNickname() {
50 |
51 | return mNickname;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/constant/Constant.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.constant;
2 |
3 | /**
4 | * @author: laohu on 2017/2/3
5 | * @site: http://ittiger.cn
6 | */
7 | public class Constant {
8 |
9 | public static final String MULTI_CHAT_ADDRESS_SPLIT = "@conference.";
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/constant/EmotionType.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.constant;
2 |
3 | import cn.ittiger.im.R;
4 | import cn.ittiger.im.fragment.BaseEmotionFragment;
5 | import cn.ittiger.im.fragment.EmotionFragment;
6 |
7 | /**
8 | * 表情类型
9 | *
10 | * @author: laohu on 2017/2/6
11 | * @site: http://ittiger.cn
12 | */
13 | public enum EmotionType {
14 | EMOTION_TYPE_CLASSIC(R.drawable.vector_keyboard_emotion, EmotionFragment.class), //经典表情
15 | EMOTION_TYPE_MORE(R.drawable.vector_emotion_more, BaseEmotionFragment.class); //+点击更多
16 |
17 | private int mEmotionTypeIcon;
18 | private Class mFragmentClass;
19 |
20 | EmotionType(int emotionTypeIcon, Class fragmentClass) {
21 |
22 | mEmotionTypeIcon = emotionTypeIcon;
23 | mFragmentClass = fragmentClass;
24 | }
25 |
26 | public int getEmotionTypeIcon() {
27 |
28 | return mEmotionTypeIcon;
29 | }
30 |
31 | public Class getFragmentClass() {
32 |
33 | return mFragmentClass;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/constant/FileLoadState.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.constant;
2 |
3 | /**
4 | * 消息接收过程中文件的加载状态
5 | * @author: laohu on 2017/1/17
6 | * @site: http://ittiger.cn
7 | */
8 | public enum FileLoadState {
9 | STATE_LOAD_START(0),//加载开始
10 | STATE_LOAD_SUCCESS(1),//加载成功
11 | STATE_LOAD_ERROR(2);//加载失败
12 |
13 | int value;
14 | FileLoadState(int value) {
15 |
16 | this.value = value;
17 | }
18 |
19 | public int value() {
20 |
21 | return value;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/constant/KeyBoardMoreFunType.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.constant;
2 |
3 | /**
4 | * KeyBoard更多功能选项类型
5 | * @author: laohu on 2017/2/4
6 | * @site: http://ittiger.cn
7 | */
8 | public enum KeyBoardMoreFunType {
9 | NONE(-1),
10 | /**
11 | * 选择图片
12 | */
13 | FUN_TYPE_IMAGE(0),
14 | /**
15 | * 拍照
16 | */
17 | FUN_TYPE_TAKE_PHOTO(1);
18 |
19 | int value;
20 |
21 | KeyBoardMoreFunType(int value) {
22 |
23 | this.value = value;
24 | }
25 |
26 | public int value() {
27 |
28 | return value;
29 | }
30 |
31 | public static KeyBoardMoreFunType getFunType(int value) {
32 |
33 | if (value == FUN_TYPE_IMAGE.value()) {
34 | return FUN_TYPE_IMAGE;
35 | } else if(value == FUN_TYPE_TAKE_PHOTO.value()) {
36 | return FUN_TYPE_TAKE_PHOTO;
37 | } else {
38 | return NONE;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/constant/MessageType.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.constant;
2 |
3 | /**
4 | * 消息类型
5 | * @author: laohu on 2017/1/12
6 | * @site: http://ittiger.cn
7 | */
8 | public enum MessageType {
9 | /**
10 | * 文本消息类型
11 | */
12 | MESSAGE_TYPE_TEXT(0),
13 | /**
14 | * 图片消息类型
15 | */
16 | MESSAGE_TYPE_IMAGE(1),
17 | /**
18 | * 语音消息类型
19 | */
20 | MESSAGE_TYPE_VOICE(2);
21 |
22 | int value;
23 | MessageType(int value) {
24 |
25 | this.value = value;
26 | }
27 |
28 | public int value() {
29 |
30 | return value;
31 | }
32 |
33 | public static MessageType getMessageType(int value) {
34 |
35 | if (value == MESSAGE_TYPE_IMAGE.value()) {
36 | return MESSAGE_TYPE_IMAGE;
37 | } else if(value == MESSAGE_TYPE_TEXT.value()) {
38 | return MESSAGE_TYPE_TEXT;
39 | } else {
40 | return MESSAGE_TYPE_VOICE;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/decoration/CommonItemDecoration.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.decoration;
2 |
3 | import cn.ittiger.app.AppContext;
4 | import cn.ittiger.im.R;
5 |
6 | import android.graphics.Canvas;
7 | import android.graphics.Rect;
8 | import android.graphics.drawable.ColorDrawable;
9 | import android.graphics.drawable.Drawable;
10 | import android.support.v7.widget.RecyclerView;
11 | import android.view.View;
12 |
13 | /**
14 | * 聊天记录列表分割线
15 | * @author: laohu on 2016/12/27
16 | * @site: http://ittiger.cn
17 | */
18 | public class CommonItemDecoration extends RecyclerView.ItemDecoration {
19 |
20 | private final Drawable mDivider;
21 | private final int mSize;
22 |
23 | public CommonItemDecoration() {
24 |
25 | mDivider = new ColorDrawable(AppContext.getInstance().getResources().getColor(R.color.divider_color));
26 | mSize = AppContext.getInstance().getResources().getDimensionPixelSize(R.dimen.global_divider_size);
27 | }
28 |
29 | @Override
30 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
31 |
32 | outRect.set(0, 0, 0, mSize);
33 | }
34 |
35 | @Override
36 | public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
37 |
38 | super.onDraw(c, parent, state);
39 | int top;
40 | int bottom;
41 | int left = parent.getPaddingLeft();
42 | int right = parent.getWidth() - parent.getPaddingRight();
43 | final int childCount = parent.getChildCount();
44 | for (int i = 0; i < childCount; i++) {
45 | final View child = parent.getChildAt(i);
46 | //获得child的布局信息
47 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)child.getLayoutParams();
48 | top = child.getBottom() + params.bottomMargin;
49 | bottom = top + mSize;
50 | mDivider.setBounds(left, top, right, bottom);
51 | mDivider.draw(c);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/decoration/CommonVerticalItemDecoration.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.decoration;
2 |
3 | import cn.ittiger.app.AppContext;
4 | import cn.ittiger.im.R;
5 |
6 | import android.graphics.Canvas;
7 | import android.graphics.Rect;
8 | import android.graphics.drawable.ColorDrawable;
9 | import android.graphics.drawable.Drawable;
10 | import android.support.v7.widget.RecyclerView;
11 | import android.view.View;
12 |
13 | /**
14 | * 列表垂直分割线
15 | * @author: laohu on 2017/2/6
16 | * @site: http://ittiger.cn
17 | */
18 | public class CommonVerticalItemDecoration extends RecyclerView.ItemDecoration {
19 |
20 | private final Drawable mDivider;
21 | private final int mSize;
22 |
23 | public CommonVerticalItemDecoration() {
24 |
25 | mDivider = new ColorDrawable(AppContext.getInstance().getResources().getColor(R.color.divider_color));
26 | mSize = AppContext.getInstance().getResources().getDimensionPixelSize(R.dimen.global_divider_size);
27 | }
28 |
29 | @Override
30 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
31 |
32 | outRect.set(0, 0, mSize, 0);
33 | }
34 |
35 | @Override
36 | public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
37 |
38 | super.onDraw(c, parent, state);
39 | int top = parent.getPaddingTop();
40 | int bottom = parent.getHeight() - parent.getPaddingTop();
41 | int left;
42 | int right;
43 | final int childCount = parent.getChildCount();
44 | for (int i = 0; i < childCount; i++) {
45 | final View child = parent.getChildAt(i);
46 | //获得child的布局信息
47 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)child.getLayoutParams();
48 | left = child.getRight() + params.rightMargin;
49 | right = left + mSize;
50 | mDivider.setBounds(left, top, right, bottom);
51 | mDivider.draw(c);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/fragment/BaseEmotionFragment.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.fragment;
2 |
3 | import cn.ittiger.im.constant.EmotionType;
4 |
5 | import android.support.v4.app.Fragment;
6 | import android.widget.EditText;
7 |
8 | /**
9 | * @author: laohu on 2017/2/6
10 | * @site: http://ittiger.cn
11 | */
12 | public class BaseEmotionFragment extends Fragment {
13 | protected EmotionType mEmotionType;
14 | protected EditText mEditText;
15 |
16 | public BaseEmotionFragment() {
17 |
18 | }
19 |
20 | public void setEmotionType(EmotionType emotionType) {
21 |
22 | mEmotionType = emotionType;
23 | }
24 |
25 | public void bindToEditText(EditText editText) {
26 |
27 | mEditText = editText;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/smack/MultiChatInvitationListener.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.smack;
2 |
3 | import cn.ittiger.im.bean.ChatUser;
4 | import cn.ittiger.im.constant.Constant;
5 | import cn.ittiger.im.util.DBHelper;
6 | import cn.ittiger.im.util.LoginHelper;
7 |
8 | import com.orhanobut.logger.Logger;
9 |
10 | import org.jivesoftware.smack.XMPPConnection;
11 | import org.jivesoftware.smack.packet.Message;
12 | import org.jivesoftware.smackx.muc.InvitationListener;
13 | import org.jivesoftware.smackx.muc.MultiUserChat;
14 |
15 | /**
16 | * 多人聊天邀请监听
17 | * @author: laohu on 2017/1/24
18 | * @site: http://ittiger.cn
19 | */
20 | public class MultiChatInvitationListener implements InvitationListener {
21 |
22 | @Override
23 | public void invitationReceived(XMPPConnection conn, MultiUserChat room, String inviter,
24 | String reason, String password, Message message) {
25 |
26 | try {
27 | room.join(LoginHelper.getUser().getNickname());
28 | SmackMultiChatManager.saveMultiChat(room);
29 | SmackListenerManager.addMultiChatMessageListener(room);
30 |
31 | String friendUserName = room.getRoom();
32 | int idx = friendUserName.indexOf(Constant.MULTI_CHAT_ADDRESS_SPLIT);
33 | String friendNickName = friendUserName.substring(0, idx);
34 | ChatUser chatUser = new ChatUser(friendUserName, friendNickName, true);
35 | DBHelper.getInstance().getSQLiteDB().save(chatUser);
36 | } catch (Exception e) {
37 | Logger.e(e, "join multiChat failure on invitationReceived");
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/smack/MultiChatMessageListener.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.smack;
2 |
3 | import cn.ittiger.im.bean.ChatMessage;
4 | import cn.ittiger.im.constant.MessageType;
5 | import cn.ittiger.im.util.DBHelper;
6 | import cn.ittiger.im.util.LoginHelper;
7 |
8 | import com.orhanobut.logger.Logger;
9 |
10 | import org.greenrobot.eventbus.EventBus;
11 | import org.jivesoftware.smack.MessageListener;
12 | import org.jivesoftware.smack.packet.Message;
13 | import org.json.JSONObject;
14 |
15 | import java.util.regex.Matcher;
16 | import java.util.regex.Pattern;
17 |
18 | /**
19 | * 多人聊天消息监听
20 | * @author: laohu on 2017/1/24
21 | * @site: http://ittiger.cn
22 | */
23 | public class MultiChatMessageListener implements MessageListener {
24 | private static final String PATTERN = "[a-zA-Z0-9_]+@";
25 | private String mMeNickName = LoginHelper.getUser().getNickname();
26 | private String mMeUserName = LoginHelper.getUser().getUsername();
27 |
28 | @Override
29 | public void processMessage(Message message) {
30 |
31 | //不会收到自己发送过来的消息
32 | Logger.d(message.toString());
33 | String from = message.getFrom();//消息发送人,格式:老胡创建的群@conference.121.42.13.79/老胡 --> 老胡发送的
34 | String to = message.getTo();//消息接收人(当前登陆用户),格式:zhangsan@121.42.13.79/Smack
35 | Matcher matcherTo = Pattern.compile(PATTERN).matcher(to);
36 |
37 | if(matcherTo.find()) {
38 | try {
39 | String[] fromUsers = from.split("/");
40 | String friendUserName = fromUsers[0];//老胡创建的群@conference.121.42.13.79
41 | String friendNickName = fromUsers[1];//发送人的昵称,用于聊天窗口中显示
42 |
43 | JSONObject json = new JSONObject(message.getBody());
44 |
45 | ChatMessage chatMessage = new ChatMessage(MessageType.MESSAGE_TYPE_TEXT.value(), false);
46 | chatMessage.setFriendUsername(friendUserName);
47 | chatMessage.setFriendNickname(friendNickName);
48 | chatMessage.setMeUsername(mMeUserName);
49 | chatMessage.setMeNickname(mMeNickName);
50 | chatMessage.setContent(json.optString(ChatMessage.KEY_MESSAGE_CONTENT));
51 |
52 | String sendUser = json.optString(ChatMessage.KEY_MULTI_CHAT_SEND_USER);
53 | chatMessage.setMeSend(mMeUserName.equals(sendUser));
54 | chatMessage.setMulti(true);
55 |
56 | DBHelper.getInstance().getSQLiteDB().save(chatMessage);
57 | EventBus.getDefault().post(chatMessage);
58 | } catch (Exception e) {
59 | Logger.e(e, "发送的消息格式不正确");
60 | }
61 | } else {
62 | Logger.e("发送人格式不正确");
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/smack/SmackConnectionListener.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.smack;
2 |
3 | import com.orhanobut.logger.Logger;
4 |
5 | import org.jivesoftware.smack.ConnectionListener;
6 | import org.jivesoftware.smack.XMPPConnection;
7 |
8 | /**
9 | * 服务器连接监听
10 | * @author: laohu on 2017/1/18
11 | * @site: http://ittiger.cn
12 | */
13 | public class SmackConnectionListener implements ConnectionListener {
14 |
15 | @Override
16 | public void connected(XMPPConnection connection) {
17 |
18 | Logger.d("connection connected");
19 | }
20 |
21 | @Override
22 | public void authenticated(XMPPConnection connection, boolean resumed) {
23 |
24 | Logger.d("connection authenticated");
25 | }
26 |
27 | @Override
28 | public void connectionClosed() {
29 |
30 | Logger.d("connection connectionClosed");
31 | }
32 |
33 | @Override
34 | public void connectionClosedOnError(Exception e) {
35 |
36 | Logger.d("connectionClosedOnError");
37 | }
38 |
39 | @Override
40 | public void reconnectingIn(int seconds) {
41 |
42 | Logger.d("connection reconnectingIn " + seconds + " second");
43 | }
44 |
45 | @Override
46 | public void reconnectionFailed(Exception e) {
47 |
48 | Logger.d("reconnectionFailed");
49 | }
50 |
51 | @Override
52 | public void reconnectionSuccessful() {
53 |
54 | Logger.d("reconnectionSuccessful");
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/ui/ChatPromptDialog.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.ui;
2 |
3 | import cn.ittiger.im.R;
4 | import cn.ittiger.im.bean.ContactEntity;
5 | import cn.ittiger.im.util.IMUtil;
6 | import cn.ittiger.im.util.IntentHelper;
7 |
8 | import org.greenrobot.eventbus.EventBus;
9 |
10 | import android.content.Context;
11 | import android.content.DialogInterface;
12 | import android.support.v7.app.AlertDialog;
13 |
14 | /**
15 | * 联系人列表
16 | * @author: laohu on 2016/12/24
17 | * @site: http://ittiger.cn
18 | */
19 | public class ChatPromptDialog implements DialogInterface.OnClickListener {
20 |
21 | private AlertDialog mDialog;
22 | private Context mContext;
23 | private ContactEntity mContactEntity;
24 |
25 | public ChatPromptDialog(Context context) {
26 |
27 | mContext = context;
28 | }
29 |
30 | public void show(ContactEntity contactEntity) {
31 |
32 | mContactEntity = contactEntity;
33 | String message = String.format(mContext.getString(R.string.chat_dialog_message), contactEntity.getRosterEntry().getName());
34 |
35 | if(mDialog == null) {
36 | AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
37 | builder.setTitle(mContext.getString(R.string.chat_dialog_title))
38 | .setCancelable(true)
39 | .setNegativeButton(mContext.getString(R.string.cancel), this)
40 | .setPositiveButton(mContext.getString(R.string.ok), this);
41 | mDialog = builder.create();
42 | }
43 | mDialog.setMessage(message);
44 | mDialog.show();
45 | }
46 |
47 | @Override
48 | public void onClick(DialogInterface dialog, int which) {
49 |
50 | if(which == DialogInterface.BUTTON_POSITIVE) {
51 | dialog.dismiss();
52 | IMUtil.startChatActivity(mContext, mContactEntity.getRosterEntry());
53 | EventBus.getDefault().post(Integer.valueOf(IntentHelper.MESSAGE_TAB_INDEX));
54 | mContactEntity = null;
55 | } else if(which == DialogInterface.BUTTON_NEGATIVE) {
56 | dialog.dismiss();
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/ui/ClearEditText.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.ui;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.graphics.drawable.Drawable;
6 | import android.text.Editable;
7 | import android.text.TextWatcher;
8 | import android.util.AttributeSet;
9 | import android.view.MotionEvent;
10 | import android.widget.EditText;
11 | import cn.ittiger.im.R;
12 |
13 | /**
14 | * 可清除的EditText
15 | * @auther: hyl
16 | * @time: 2015-10-20下午3:02:42
17 | */
18 | public class ClearEditText extends EditText {
19 | /**
20 | * 清除图标是否显示
21 | */
22 | private boolean mClearIconVisible = false;
23 | /**
24 | * 清除图标
25 | */
26 | private Drawable mClearIcon;
27 |
28 | public ClearEditText(Context context, AttributeSet attrs, int defStyle) {
29 | super(context, attrs, defStyle);
30 | initView(context);
31 | }
32 |
33 | public ClearEditText(Context context, AttributeSet attrs) {
34 | super(context, attrs);
35 | initView(context);
36 | }
37 |
38 | public ClearEditText(Context context) {
39 | super(context);
40 | initView(context);
41 | }
42 |
43 | private void initView(Context context) {
44 | mClearIcon = getResources().getDrawable(R.drawable.tigerframe_edittext_clear);
45 | mClearIcon.setBounds(0, 0, mClearIcon.getMinimumWidth(), mClearIcon.getMinimumHeight());
46 |
47 | addTextChangedListener(new TextWatcher() {
48 | @Override
49 | public void onTextChanged(CharSequence s, int start, int before, int count) {
50 |
51 | }
52 |
53 | @Override
54 | public void beforeTextChanged(CharSequence s, int start, int count,
55 | int after) {
56 |
57 | }
58 |
59 | @Override
60 | public void afterTextChanged(Editable s) {
61 | String text = getText().toString();
62 | if(isFocused() && text != null && !text.isEmpty()) {
63 | if(!mClearIconVisible) {
64 | setCompoundDrawables(null, null, mClearIcon, null);
65 | mClearIconVisible = true;
66 | }
67 | } else {
68 | setCompoundDrawables(null, null, null, null);
69 | mClearIconVisible = false;
70 | }
71 | }
72 | });
73 | }
74 |
75 | /**
76 | * 添加触摸事件 点击之后 出现 清空editText的效果
77 | */
78 | @SuppressLint("ClickableViewAccessibility")
79 | @Override
80 | public boolean onTouchEvent(MotionEvent motionEvent) {
81 | if(mClearIconVisible && mClearIcon != null && motionEvent.getAction() == MotionEvent.ACTION_UP) {
82 | if(motionEvent.getX() > getWidth() - getPaddingRight() - mClearIcon.getIntrinsicWidth()) {
83 | setText("");
84 | motionEvent.setAction(MotionEvent.ACTION_CANCEL);
85 | }
86 | }
87 | return super.onTouchEvent(motionEvent);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/ui/RecordingVoiceView.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.ui;
2 |
3 | import butterknife.BindView;
4 | import butterknife.ButterKnife;
5 | import cn.ittiger.im.R;
6 |
7 | import android.content.Context;
8 | import android.os.Build;
9 | import android.support.annotation.RequiresApi;
10 | import android.util.AttributeSet;
11 | import android.view.View;
12 | import android.widget.FrameLayout;
13 |
14 | /**
15 | * Created by ylhu on 17-2-7.
16 | */
17 | public class RecordingVoiceView extends FrameLayout {
18 | @BindView(R.id.recording_voice_container)
19 | View mRecordingContainer;
20 | @BindView(R.id.cancel_recording_voice_container)
21 | View mCancelRecordingContainer;
22 |
23 | public RecordingVoiceView(Context context) {
24 |
25 | super(context);
26 | initView(context);
27 | }
28 |
29 | public RecordingVoiceView(Context context, AttributeSet attrs) {
30 |
31 | super(context, attrs);
32 | initView(context);
33 | }
34 |
35 | public RecordingVoiceView(Context context, AttributeSet attrs, int defStyleAttr) {
36 |
37 | super(context, attrs, defStyleAttr);
38 | initView(context);
39 | }
40 |
41 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
42 | public RecordingVoiceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
43 |
44 | super(context, attrs, defStyleAttr, defStyleRes);
45 | initView(context);
46 | }
47 |
48 | private void initView(Context context) {
49 |
50 | inflate(context, R.layout.keyboard_recording_voice_layout, this);
51 | ButterKnife.bind(this);
52 | setBackgroundResource(R.drawable.recording_vocie_view_bg);
53 | setAlpha(0.6f);
54 | }
55 |
56 | public void showStartRecordingView() {
57 |
58 | if(getVisibility() == GONE) {
59 | setVisibility(VISIBLE);
60 | }
61 | if(mRecordingContainer.getVisibility() == GONE) {
62 | mRecordingContainer.setVisibility(VISIBLE);
63 | }
64 | if(mCancelRecordingContainer.getVisibility() == VISIBLE) {
65 | mCancelRecordingContainer.setVisibility(GONE);
66 | }
67 | }
68 |
69 | public void showCancelRecordingView() {
70 |
71 | if(getVisibility() == GONE) {
72 | setVisibility(VISIBLE);
73 | }
74 | if(mRecordingContainer.getVisibility() == VISIBLE) {
75 | mRecordingContainer.setVisibility(GONE);
76 | }
77 | if(mCancelRecordingContainer.getVisibility() == GONE) {
78 | mCancelRecordingContainer.setVisibility(VISIBLE);
79 | }
80 | }
81 |
82 | public void hide() {
83 |
84 | setVisibility(GONE);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/ui/keyboard/emotion/EmotionItemClickListener.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.ui.keyboard.emotion;
2 |
3 | import cn.ittiger.im.adapter.EmotionAdapter;
4 | import cn.ittiger.im.constant.EmotionType;
5 | import cn.ittiger.im.util.EmotionUtil;
6 |
7 | import android.content.Context;
8 | import android.view.KeyEvent;
9 | import android.view.View;
10 | import android.widget.AdapterView;
11 | import android.widget.EditText;
12 | import android.widget.GridView;
13 |
14 | /**
15 | * @author: laohu on 2017/2/6
16 | * @site: http://ittiger.cn
17 | */
18 | public class EmotionItemClickListener implements GridView.OnItemClickListener {
19 | private Context mContext;
20 | private EditText mEditText;
21 | private EmotionType mEmotionType;
22 |
23 | public EmotionItemClickListener(Context context, EditText editText, EmotionType emotionType) {
24 |
25 | mContext = context;
26 | mEditText = editText;
27 | mEmotionType = emotionType;
28 | }
29 |
30 | @Override
31 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
32 |
33 | if(!(parent.getAdapter() instanceof EmotionAdapter)) {
34 | return;
35 | }
36 | EmotionAdapter adapter = (EmotionAdapter) parent.getAdapter();
37 | if(position == adapter.getCount() - 1) {//点击了最后一个,即删除表情按钮
38 | //发送一个删除事件交给系统进行删除操作
39 | mEditText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
40 | } else {//点击了表情,则添加到输入框
41 | String emotionName = adapter.getItem(position);//得到点击表情的名称
42 |
43 | // 获取输入框当前光标位置,在指定位置上添加表情图片文本
44 | int curPosition = mEditText.getSelectionStart();
45 | StringBuilder sb = new StringBuilder(mEditText.getText().toString());
46 | sb.insert(curPosition, emotionName);
47 |
48 | // 特殊文字处理,将表情等转换一下
49 | mEditText.setText(EmotionUtil.getInputEmotionContent(mContext, mEmotionType, mEditText, sb.toString()));
50 |
51 | // 将光标设置到新增完表情的右侧
52 | mEditText.setSelection(curPosition + emotionName.length());
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/ui/recyclerview/ViewHolder.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.ui.recyclerview;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.View;
5 |
6 | /**
7 | * Created by laohu on 16-7-19.
8 | */
9 | public class ViewHolder extends RecyclerView.ViewHolder {
10 |
11 | public ViewHolder(View itemView) {
12 |
13 | super(itemView);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/util/AppFileHelper.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.util;
2 |
3 | import cn.ittiger.app.AppContext;
4 | import cn.ittiger.im.constant.MessageType;
5 | import cn.ittiger.util.ValueUtil;
6 |
7 | import java.io.File;
8 |
9 | /**
10 | * 应用相关文件帮助类
11 | * @author: laohu on 2017/1/18
12 | * @site: http://ittiger.cn
13 | */
14 | public class AppFileHelper {
15 |
16 | public static String getAppRoot() {
17 |
18 | return AppContext.getInstance().getExternalCacheDir().getAbsolutePath();
19 | }
20 |
21 | public static String getAppImageCacheDir() {
22 |
23 | return getAppRoot() + "/image";
24 | }
25 |
26 | public static String getAppDBDir() {
27 |
28 | return getAppRoot() + "/db";
29 | }
30 |
31 | public static String getAppCrashDir() {
32 |
33 | return getAppRoot() + "/crash";
34 | }
35 |
36 | public static String getAppChatDir() {
37 |
38 | return getAppRoot() + "/chat";
39 | }
40 |
41 | public static File getAppChatMessageDir(int type) {
42 |
43 | String root = getAppChatDir();
44 | String child = "";
45 | if(type == MessageType.MESSAGE_TYPE_IMAGE.value()) {
46 | child = "recv_image";
47 | } else if(type == MessageType.MESSAGE_TYPE_VOICE.value()) {
48 | child = "recv_voice";
49 | }
50 | File file;
51 | if(ValueUtil.isEmpty(child)) {
52 | file = new File(root);
53 | } else {
54 | file = new File(root, child);
55 | }
56 | if(!file.exists()) {
57 | file.mkdirs();
58 | }
59 | return file;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/util/DBHelper.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.util;
2 |
3 | import cn.ittiger.app.AppContext;
4 | import cn.ittiger.database.SQLiteDB;
5 | import cn.ittiger.database.SQLiteDBConfig;
6 | import cn.ittiger.database.SQLiteDBFactory;
7 | import cn.ittiger.im.app.App;
8 | import cn.ittiger.im.app.IDbApplication;
9 |
10 | /**
11 | * 本地数据库管理类
12 | * @author laohu
13 | */
14 | public class DBHelper {
15 | /**
16 | * 管理器单例
17 | */
18 | private static DBHelper sDBInstance;
19 | /**
20 | * 数据库配置上下文
21 | */
22 | private IDbApplication mDbApplication;
23 | /**
24 | * 全局数据库
25 | */
26 | private SQLiteDB mDB;
27 |
28 |
29 | private DBHelper() {
30 |
31 | mDbApplication = ((App) AppContext.getInstance().getApplicationContext());
32 | }
33 |
34 | public static DBHelper getInstance() {
35 |
36 | if(sDBInstance == null) {
37 | synchronized (DBHelper.class) {
38 | if(sDBInstance == null) {
39 | sDBInstance = new DBHelper();
40 | }
41 | }
42 | }
43 | return sDBInstance;
44 | }
45 |
46 | /**
47 | * 获取全局数据库操作对象
48 | * @return
49 | */
50 | public SQLiteDB getSQLiteDB() {
51 |
52 | if(mDB == null) {
53 | synchronized (this) {
54 | if(mDB == null) {
55 | SQLiteDBConfig config = mDbApplication.getGlobalDbConfig();
56 | mDB = SQLiteDBFactory.createSQLiteDB(config);
57 | }
58 | }
59 | }
60 | return mDB;
61 | }
62 |
63 | /**
64 | * 关闭数据库
65 | */
66 | public void closeSQLiteDB() {
67 | if(this.mDB != null) {
68 | this.mDB.close();
69 | }
70 | this.mDB = null;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/util/ImageLoaderHelper.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.util;
2 |
3 | import cn.ittiger.im.R;
4 |
5 | import com.nostra13.universalimageloader.core.DisplayImageOptions;
6 | import com.nostra13.universalimageloader.core.ImageLoader;
7 | import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
8 |
9 | import android.graphics.Bitmap;
10 | import android.widget.ImageView;
11 |
12 | /**
13 | * 图片参数帮助类
14 | * @author: laohu on 2016/12/24
15 | * @site: http://ittiger.cn
16 | */
17 | public class ImageLoaderHelper {
18 |
19 | /*
20 | String imageUri = "http://site.com/image.png"; // 网络图片
21 | String imageUri = "file:///mnt/sdcard/image.png"; // sd卡图片
22 | String imageUri = "content://media/external/audio/albumart/13"; // content provider
23 | String imageUri = "assets://image.png"; // assets文件夹图片
24 | String imageUri = "drawable://" + R.drawable.image; // drawable图片
25 | */
26 | private static volatile DisplayImageOptions sImageOptions;
27 |
28 | public static DisplayImageOptions getChatImageOptions() {
29 |
30 | if(sImageOptions == null) {
31 | synchronized (ImageLoaderHelper.class) {
32 | if(sImageOptions == null) {
33 | sImageOptions = new DisplayImageOptions.Builder()
34 | .cacheOnDisk(true)//图片下载后是否缓存到SDCard
35 | .cacheInMemory(true)//图片下载后是否缓存到内存
36 | .bitmapConfig(Bitmap.Config.RGB_565)//图片解码类型,推荐此种方式,减少OOM
37 | .considerExifParams(true)//是否考虑JPEG图像EXIF参数(旋转,翻转)
38 | .resetViewBeforeLoading(true)//设置图片在下载前是否重置,复位
39 | .showImageOnFail(R.drawable.vector_default_image)//图片加载失败后显示的图片
40 | .showImageOnLoading(R.drawable.vector_default_image)
41 | .build();
42 | }
43 | }
44 | }
45 | return sImageOptions;
46 | }
47 |
48 | public static void displayImage(ImageView imageView, String url) {
49 |
50 | displayImage(imageView, url, null);
51 | }
52 |
53 | public static void displayImage(ImageView imageView, String url, ImageLoadingListener imageLoadingListener) {
54 |
55 | ImageLoader.getInstance().displayImage(url, imageView, getChatImageOptions(), imageLoadingListener);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/util/IntentHelper.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.util;
2 |
3 | /**
4 | * Intent间传递参数的帮助类
5 | * @author: laohu on 2017/1/12
6 | * @site: http://ittiger.cn
7 | */
8 | public class IntentHelper {
9 | public static final String KEY_CHAT_DIALOG = "key_chat_dialog";//从联系人中发起聊天时传递参数的key
10 | public static final int MESSAGE_TAB_INDEX = 0;//主界面中消息Fragment的索引
11 | public static final int CONTACT_TAB_INDEX = 1;//主界面中联系人Fragment的索引
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/util/LoginHelper.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.util;
2 |
3 | import cn.ittiger.im.bean.User;
4 | import cn.ittiger.util.PreferenceHelper;
5 |
6 | /**
7 | * Created by laohu on 16-12-14.
8 | */
9 | public class LoginHelper {
10 |
11 | private static final String KEY_REMEMBER_PASSWORD = "pre_key_remember_password";
12 | private static final String KEY_USER = "pre_key_user";
13 |
14 | /**
15 | * 是否记住密码
16 | *
17 | * @return
18 | */
19 | public static boolean isRememberPassword() {
20 |
21 | return PreferenceHelper.getBoolean(KEY_REMEMBER_PASSWORD, false);
22 | }
23 |
24 | public static void rememberRassword(boolean isRemember) {
25 |
26 | PreferenceHelper.putBoolean(KEY_REMEMBER_PASSWORD, isRemember);
27 | }
28 |
29 | public static User getUser() {
30 |
31 | User user = (User) PreferenceHelper.get(KEY_USER);
32 | if(user == null) {
33 | user = new User("", "");
34 | }
35 | return user;
36 | }
37 |
38 | public static void saveUser(User user) {
39 |
40 | PreferenceHelper.put(KEY_USER, user);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/ittiger/im/util/ShareHelper.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im.util;
2 |
3 | import cn.ittiger.im.R;
4 | import cn.ittiger.util.UIUtil;
5 |
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.content.pm.PackageInfo;
9 | import android.content.pm.PackageManager;
10 | import android.net.Uri;
11 |
12 | import java.io.File;
13 |
14 | /**
15 | * @author laohu
16 | * @site http://ittiger.cn
17 | */
18 | public class ShareHelper {
19 |
20 | public static void shareApp(Context context) {
21 |
22 | String packageName = context.getPackageName();
23 | try {
24 | PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
25 | File sourceFile=new File(packageInfo.applicationInfo.sourceDir);
26 | //调用android系统的分享窗口
27 | Intent intent = new Intent(Intent.ACTION_SEND);
28 | intent.setType("*/*");
29 | intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(sourceFile));
30 | context.startActivity(Intent.createChooser(intent, context.getString(R.string.share_app_title)));
31 | } catch (PackageManager.NameNotFoundException e) {
32 | UIUtil.showToast(context, "分享失败");
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/res/color/tabbar_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-hdpi/avatar.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/bg_launcher.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-hdpi/bg_launcher.jpeg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/pic_default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-hdpi/pic_default.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/tigerframe_edittext_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-hdpi/tigerframe_edittext_clear.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/tigerframe_icon_back_btn_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-hdpi/tigerframe_icon_back_btn_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/tigerframe_icon_back_btn_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-hdpi/tigerframe_icon_back_btn_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/about_img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/about_img.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/avatar.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/chat_from_bg_normal.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/chat_from_bg_normal.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/chat_from_bg_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/chat_from_bg_pressed.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/chat_to_bg_normal.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/chat_to_bg_normal.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/chat_to_bg_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/chat_to_bg_pressed.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_aini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_aini.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_aoteman.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_aoteman.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_baibai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_baibai.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_beishang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_beishang.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_bishi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_bishi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_bizui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_bizui.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_chanzui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_chanzui.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_chijing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_chijing.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_dahaqi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_dahaqi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_dalian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_dalian.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_ding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_ding.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_doge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_doge.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_fangdumianju.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_fangdumianju.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_feizao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_feizao.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_ganmao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_ganmao.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_guzhang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_guzhang.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_haha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_haha.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_haixiu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_haixiu.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_han.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_han.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_hehe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_hehe.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_heixian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_heixian.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_heng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_heng.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_huaxin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_huaxin.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_jiyan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_jiyan.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_keai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_keai.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_kelian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_kelian.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_ku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_ku.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_kun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_kun.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_landelini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_landelini.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_lang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_lang.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_lei.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_lei.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_miao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_miao.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_nanhaier.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_nanhaier.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_nu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_nu.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_numa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_numa.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_nvhaier.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_nvhaier.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_qian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_qian.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_qinqin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_qinqin.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_shayan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_shayan.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_shengbing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_shengbing.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_shenshou.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_shenshou.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_shiwang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_shiwang.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_shuai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_shuai.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_shuijiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_shuijiao.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_sikao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_sikao.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_taikaixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_taikaixin.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_touxiao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_touxiao.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_travel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_travel.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_tu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_tu.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_tuzi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_tuzi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_wabishi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_wabishi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_weiqu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_weiqu.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_xiaoku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_xiaoku.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_xiongmao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_xiongmao.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_xixi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_xixi.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_xu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_xu.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_yinxian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_yinxian.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_yiwen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_yiwen.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_youhengheng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_youhengheng.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_yun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_yun.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_zhuakuang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_zhuakuang.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_zhutou.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_zhutou.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_zuiyou.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_zuiyou.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/d_zuohengheng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/d_zuohengheng.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/file_load_fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/file_load_fail.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/gxu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/gxu.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/gxv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/gxv.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/gxw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/gxw.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/gxx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/gxx.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/gxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/gxy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/gxz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/gxz.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_chat_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/icon_chat_image.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_chat_take_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/icon_chat_take_photo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/loading1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/loading1.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/loading2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/loading2.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/loading3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/drawable-xxhdpi/loading3.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/anim_chat_voice_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/anim_chat_voice_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_chat_time_tag.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/chat_file_content_loading_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/chat_from_bg_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/chat_to_bg_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_emotion.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_more.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_voice.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_tabbar_contact.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_tabbar_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_toolbar_add.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_toolbar_avatar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/keyboard_emotion_indicator_nomal_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/keyboard_emotion_indicator_select_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/keyboard_input_edittext_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
9 |
10 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/keyboard_record_voice_button_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
8 |
9 |
10 |
11 | -
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/main_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/main_button_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
7 |
9 |
10 |
11 | -
12 |
13 |
15 |
17 |
18 |
19 | -
20 |
21 |
23 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/recording_vocie_view_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/recording_voice_cancel_text_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/tigerframe_icon_back_btn_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_about.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_add.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_add_focus.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_avatar.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_avatar_focus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_chat_avatar.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_checked.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_contact.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_contact_focus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_contact_group.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_default_image.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_emotion_more.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_emotion.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_emotion_delete.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_emotion_focus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_more.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_more_focus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_normal.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_pressed.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_text.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_text_focus.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_voice.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_keyboard_voice_focus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_message.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_message_focus.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_multi_chat.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_recording_cancel.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_recording_voice.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_share.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/vector_uncheck.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_account_mng_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
17 |
22 |
27 |
32 |
33 |
34 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_chat_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
18 |
19 |
25 |
26 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_create_multi_chat.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
22 |
23 |
27 |
28 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_nav_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
20 |
21 |
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_multichat_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
18 |
19 |
25 |
26 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_webpage.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
11 |
12 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_keyboard_emotion_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_keyboard_emotion_tab_item_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_keyboard_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
39 |
40 |
41 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_keyboard_more_item_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_keyboard_more_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_record_item_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
25 |
32 |
40 |
41 |
42 |
47 |
53 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/checkable_contact_item_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
24 |
25 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/contact_item_index_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/contact_item_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/divider_horizontal_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_contact.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_emotion_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tabbar_item_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/create_multi_chat_toolbar_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main_toolbar_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @drawable/icon_chat_image
5 | - @drawable/icon_chat_take_photo
6 |
7 |
8 |
9 | - @string/keyboard_more_image
10 | - @string/keyboard_more_take_photo
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | @color/main_color
6 |
7 | #FFFFFF
8 | #000000
9 | #00000000
10 | #18B5EA
11 |
12 | #c9c9c9
13 | #f6f5f5
14 | #e6e6e6
15 | #8a8a8a
16 |
17 | #ECECEC
18 | #bfbfbf
19 | #8a8a8a
20 | #515151
21 | #c9c9c9
22 | #bfbfbf
23 | @color/chat_keyboard_bg
24 | #D8D8D8
25 | #A6A6A6
26 | #DE000000
27 | #ab2100
28 |
29 | #2C2C2C
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1dp
4 | 2dp
5 | 3dp
6 | 4dp
7 | 5dp
8 | 8dp
9 | 10dp
10 | 12dp
11 | 15dp
12 | 20dp
13 | 24dp
14 | 30dp
15 | 35dp
16 | 40dp
17 | 50dp
18 | 55dp
19 | 60dp
20 | 80dp
21 | 150dp
22 |
23 | 160dp
24 | 48dp
25 | 1px
26 | 10dp
27 | 24dp
28 | 20dp
29 |
30 |
31 | 12sp
32 | 14sp
33 | 18sp
34 | 11sp
35 | 18sp
36 | 18sp
37 |
38 | 16dp
39 | 16dp
40 |
41 | @dimen/dimen_10
42 |
43 |
--------------------------------------------------------------------------------
/app/src/test/java/cn/ittiger/im/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package cn.ittiger.im;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 |
14 | assertEquals(4, 2 + 2);
15 | }
16 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.2'
9 | //butterknife
10 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | jcenter()
20 | }
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
26 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 21 11:34:03 PDT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/screenshots/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/screenshots/1.jpg
--------------------------------------------------------------------------------
/screenshots/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/screenshots/2.jpg
--------------------------------------------------------------------------------
/screenshots/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huyongli/TigerIM/415c24a76f28f1a9952955d59dfc8e6731286e8a/screenshots/3.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':TigerLibrary'
2 |
--------------------------------------------------------------------------------