├── .gitignore
├── .idea
├── .name
├── codeStyles
│ └── Project.xml
├── misc.xml
└── runConfigurations.xml
├── LICENSE
├── README.md
├── apk
├── app-debug.apk
└── app-release.apk
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── release
│ └── output.json
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── api1
│ │ ├── p1.json
│ │ ├── p1_r1.json
│ │ ├── p2.json
│ │ ├── p3.json
│ │ ├── p3_r1.json
│ │ └── p3_r2.json
│ └── api2
│ │ ├── p1.json
│ │ ├── p1_r1.json
│ │ ├── p2.json
│ │ ├── p3.json
│ │ ├── p3_r1.json
│ │ └── p3_r2.json
│ ├── java
│ └── com
│ │ └── jidcoo
│ │ └── android
│ │ └── widgettest
│ │ ├── MainActivity.java
│ │ ├── custom
│ │ ├── CustomCommentModel.java
│ │ ├── CustomCommentViewHolder.java
│ │ ├── CustomReplyViewHolder.java
│ │ ├── CustomUseInLocalActivity.java
│ │ ├── CustomViewStyleConfigurator.java
│ │ └── SampleCircleImageView.java
│ │ └── simple
│ │ ├── DefaultUseInLocalActivity.java
│ │ ├── DefaultUseWithServerActivity.java
│ │ ├── HttpServer.java
│ │ └── LocalServer.java
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ ├── ic_launcher_background.xml
│ └── round_shape.xml
│ ├── layout
│ ├── activity_main.xml
│ ├── custom_item_comment.xml
│ ├── custom_item_reply.xml
│ ├── custom_use.xml
│ ├── editor.xml
│ └── simple_use.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── commentview
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── jidcoo
│ │ └── android
│ │ └── widget
│ │ └── commentview
│ │ ├── CommentView.java
│ │ ├── adapter
│ │ └── ViewAdapter.java
│ │ ├── callback
│ │ ├── CustomCommentItemCallback.java
│ │ ├── CustomReplyItemCallback.java
│ │ ├── OnCommentLoadMoreCallback.java
│ │ ├── OnConvertViewClickCallback.java
│ │ ├── OnItemClickCallback.java
│ │ ├── OnPullRefreshCallback.java
│ │ ├── OnReplyLoadMoreCallback.java
│ │ └── OnScrollCallback.java
│ │ ├── defaults
│ │ ├── DefaultCommentHolder.java
│ │ ├── DefaultCommentModel.java
│ │ ├── DefaultItemBuilder.java
│ │ ├── DefaultReplyHolder.java
│ │ └── DefaultViewStyleConfigurator.java
│ │ ├── model
│ │ ├── AbstractCommentModel.java
│ │ ├── CommentEnable.java
│ │ ├── PagerEnable.java
│ │ └── ReplyEnable.java
│ │ ├── operator
│ │ ├── AbsAdapterOperator.java
│ │ ├── AbsOperator.java
│ │ ├── AdapterOperator.java
│ │ └── CommentViewOperator.java
│ │ ├── utils
│ │ └── ViewUtil.java
│ │ └── view
│ │ ├── CommentListView.java
│ │ ├── LoadingMoreFootView.java
│ │ ├── RoundAngleImageView.java
│ │ ├── ViewHolder.java
│ │ └── ViewStyleConfigurator.java
│ └── res
│ ├── drawable
│ ├── ico.png
│ └── pxjh.png
│ ├── layout
│ ├── commentview.xml
│ ├── footer_layout.xml
│ ├── item_comment.xml
│ ├── item_loadmore.xml
│ └── item_reply.xml
│ └── values
│ ├── attr.xml
│ ├── ids.xml
│ └── strings.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | <<<<<<< HEAD
2 | *.iml
3 | .gradle
4 | /local.properties
5 | /.idea/caches
6 | /.idea/libraries
7 | /.idea/modules.xml
8 | /.idea/workspace.xml
9 | /.idea/navEditor.xml
10 | /.idea/assetWizardSettings.xml
11 | .DS_Store
12 | /build
13 | /captures
14 | .externalNativeBuild
15 | .cxx
16 | =======
17 | # Built application files
18 | *.apk
19 | *.aar
20 | *.ap_
21 | *.aab
22 |
23 | # Files for the ART/Dalvik VM
24 | *.dex
25 |
26 | # Java class files
27 | *.class
28 |
29 | # Generated files
30 | bin/
31 | gen/
32 | out/
33 | # Uncomment the following line in case you need and you don't have the release build type files in your app
34 | # release/
35 |
36 | # Gradle files
37 | .gradle/
38 | build/
39 |
40 | # Local configuration file (sdk path, etc)
41 | local.properties
42 |
43 | # Proguard folder generated by Eclipse
44 | proguard/
45 |
46 | # Log Files
47 | *.log
48 |
49 | # Android Studio Navigation editor temp files
50 | .navigation/
51 |
52 | # Android Studio captures folder
53 | captures/
54 |
55 | # IntelliJ
56 | *.iml
57 | .idea/workspace.xml
58 | .idea/tasks.xml
59 | .idea/gradle.xml
60 | .idea/assetWizardSettings.xml
61 | .idea/dictionaries
62 | .idea/libraries
63 | # Android Studio 3 in .gitignore file.
64 | .idea/caches
65 | .idea/modules.xml
66 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you
67 | .idea/navEditor.xml
68 |
69 | # Keystore files
70 | # Uncomment the following lines if you do not want to check your keystore files in.
71 | #*.jks
72 | #*.keystore
73 |
74 | # External native build folder generated in Android Studio 2.2 and later
75 | .externalNativeBuild
76 | .cxx/
77 |
78 | # Google Services (e.g. APIs or Firebase)
79 | # google-services.json
80 |
81 | # Freeline
82 | freeline.py
83 | freeline/
84 | freeline_project_description.json
85 |
86 | # fastlane
87 | fastlane/report.xml
88 | fastlane/Preview.html
89 | fastlane/screenshots
90 | fastlane/test_output
91 | fastlane/readme.md
92 |
93 | # Version control
94 | vcs.xml
95 |
96 | # lint
97 | lint/intermediates/
98 | lint/generated/
99 | lint/outputs/
100 | lint/tmp/
101 | # lint/reports/
102 | >>>>>>> b7e1793011106eeac618f3468d39750dc0cb4357
103 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | WidgetTest
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
1、CustomCommentItemCallback:自定义评论布局回调
137 |2、CustomReplyItemCallback:自定义回复布局回调
138 |3、OnPullRefreshCallback:上拉刷新回调
139 |4、OnCommentLoadMoreCallback:下拉加载更多评论回调
140 |5、OnReplyLoadMoreCallback:加载更多回复回调
141 |6、OnItemClickCallback:Item的点击事件回调
142 |7、OnScrollCallback:控件滚动事件回调
143 | 144 | 当需要设置回调时: 145 | 146 | **设置完回调后必须调用.buildCallback()方法,否则回调不会生效,控件也无法正常使用。** 147 | 148 | ```java 149 | commentView.callbackBuilder() 150 | .setOnPullRefreshCallback(你的回调实例) 151 | .onItemClickCallback(你的回调实例) 152 | ......设置更多回调 153 | ......设置更多回调 154 | //设置完成后必须调用CallbackBuilder的buildCallback()方法,否则设置的回调无效,控件也无法正常显示。 155 | //无论是否设置回调,buildCallback()方法都必须调用。 156 | .buildCallback(); 157 | ``` 158 | 159 | 当不需要设置回调时: 160 | 161 | **必须调用.buildCallback()方法,否则控件也无法正常使用。** 162 | 163 | ```java 164 | commentView.callbackBuilder().buildCallback(); 165 | ``` 166 | 167 | **第五步:设置数据:** 168 | 169 | 当所有的初始化工作都完成后,就可以请求后台返回评论数据或加载本地数据为控件设置数据了。完成设置数据后,控件就能正确显示评论数据了。 170 | 171 | ```java 172 | commentView.loadComplete(你的数据模型实体类); 173 | ``` 174 | -------------------------------------------------------------------------------- /apk/app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jidcoo/CommentView/26df8f9903d0dd664bc975945b17faba2b3fba73/apk/app-debug.apk -------------------------------------------------------------------------------- /apk/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jidcoo/CommentView/26df8f9903d0dd664bc975945b17faba2b3fba73/apk/app-release.apk -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.3" 6 | defaultConfig { 7 | applicationId 8 | minSdkVersion 21 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | 23 | dependencies { 24 | implementation fileTree(dir: 'libs', include: ['*.jar']) 25 | implementation 'androidx.appcompat:appcompat:1.1.0' 26 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 27 | implementation 'com.google.code.gson:gson:2.8.6' 28 | implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' 29 | implementation project(path: ':commentview') 30 | } 31 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "outputType": { 4 | "type": "APK" 5 | }, 6 | "apkData": { 7 | "type": "MAIN", 8 | "splits": [], 9 | "versionCode": 1, 10 | "versionName": "1.0", 11 | "enabled": true, 12 | "outputFile": "app-release.apk", 13 | "fullName": "release", 14 | "baseName": "release" 15 | }, 16 | "path": "app-release.apk", 17 | "properties": {} 18 | } 19 | ] -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 |本类只对外提供控件的方法和接口
30 | *业务逻辑抽象类AbsOperator,此抽象类提供了CommentView控件所有可访问的方法,请查看{@link AbsOperator}
31 | *业务逻辑实现类CommentViewOperator,此类实现了CommentView控件所有可访问的方法,请查看{@link CommentViewOperator}
32 | *{@link #callbackBuilder()}: 获取控件的回调构造类{@link CallbackBuilder} 35 | *
{@link #loadComplete(AbstractCommentModel model)}: 首次加载完成数据后调用 36 | *
{@link #loadFailed(boolean)}: 首次加载出现错误时调用,可以控制是否显示错误视图 37 | *
{@link #refreshComplete(AbstractCommentModel model)}: 刷新数据完成后调用 38 | *
{@link #refreshFailed(String, boolean)}: 刷新出现错误时调用,可以控制是否显示错误视图 39 | *
{@link #loadMoreComplete(AbstractCommentModel model)}: 上拉加载更多数据完成后调用 40 | *
{@link #loadMoreFailed(String, boolean)}: 上拉加载更多数据出现错误时调用,可以控制是否显示错误视图 41 | *
{@link #loadMoreReplyComplete(AbstractCommentModel model)}: 加载更多回复数据完成后调用 42 | *
{@link #loadMoreReplyFailed(String, boolean)}: 加载更多回复数据出现错误时调用,可以控制是否显示错误视图 43 | *
{@link #setEmptyView(View)}: 设置数据为空时的空数据视图 44 | *
{@link #setErrorView(View)}: 设置加载失败的使用的错误视图 45 | *
{@link #setViewStyleConfigurator(ViewStyleConfigurator)}: 设置控件样式配置器,控件默认使用默认样式配置器 46 | * {@link com.jidcoo.android.widget.commentview.defaults.DefaultViewStyleConfigurator}, 47 | * 如果自定义样式配置器,请继承自{@link ViewStyleConfigurator},自定义样式配置器可参考默认样式配置器 48 | * {@link com.jidcoo.android.widget.commentview.defaults.DefaultViewStyleConfigurator} 49 | *
{@link #getCommentList()}: 获取评论数据集合 50 | *
{@link #getReplyList(int position)}:根据父级评论的位置获取父级评论回复的集合 51 | *
{@link #addComment(CommentEnable)}:添加一条评论 52 | *
{@link #addReply(ReplyEnable, int)}:给所在评论中添加一条回复 53 | *
{@link #addHeaderView(View, boolean)}:添加头部布局 54 | *
{@link #removeHeaderView(View)}:移除头部布局 55 | * @author Jidcoo 56 | * @github https://github.com/Jidcoo/ 57 | */ 58 | public class CommentView extends LinearLayout { 59 | //业务逻辑类 60 | private AbsOperator operator; 61 | 62 | ///////***CallbackBuilder***////// 63 | public final class CallbackBuilder { 64 | ///////***Callback***////// 65 | public OnPullRefreshCallback onPullRefreshCallback;//下拉刷新回调 66 | public OnCommentLoadMoreCallback onCommentLoadMoreCallback;//加载更多评论回调 67 | public OnReplyLoadMoreCallback onReplyLoadMoreCallback;//加载更多回复回调 68 | public OnItemClickCallback onItemClickCallback;//点击事件回调 69 | public OnScrollCallback onScrollCallback;//滚动事件回调 70 | public CustomCommentItemCallback customCommentItemCallback;//自定义评论布局回调 71 | public CustomReplyItemCallback customReplyItemCallback;//自定义回复布局回调 72 | 73 | ///////***Callback***////// 74 | public CallbackBuilder setOnPullRefreshCallback(OnPullRefreshCallback onPullRefreshCallback) { 75 | this.onPullRefreshCallback = onPullRefreshCallback; 76 | return this; 77 | } 78 | 79 | public CallbackBuilder setOnCommentLoadMoreCallback(OnCommentLoadMoreCallback onCommentLoadMoreCallback) { 80 | this.onCommentLoadMoreCallback = onCommentLoadMoreCallback; 81 | return this; 82 | } 83 | 84 | public CallbackBuilder setOnReplyLoadMoreCallback(OnReplyLoadMoreCallback onReplyLoadMoreCallback) { 85 | this.onReplyLoadMoreCallback = onReplyLoadMoreCallback; 86 | return this; 87 | } 88 | 89 | public CallbackBuilder setOnItemClickCallback(OnItemClickCallback onItemClickCallback) { 90 | this.onItemClickCallback = onItemClickCallback; 91 | return this; 92 | } 93 | 94 | public CallbackBuilder setOnScrollCallback(OnScrollCallback onScrollCallback) { 95 | this.onScrollCallback = onScrollCallback; 96 | return this; 97 | } 98 | 99 | public CallbackBuilder customCommentItem(CustomCommentItemCallback customCommentItemCallback) { 100 | this.customCommentItemCallback = customCommentItemCallback; 101 | return this; 102 | } 103 | 104 | public CallbackBuilder customReplyItem(CustomReplyItemCallback customReplyItemCallback) { 105 | this.customReplyItemCallback = customReplyItemCallback; 106 | return this; 107 | } 108 | 109 | public CommentView buildCallback() { 110 | return initialize(this); 111 | } 112 | } 113 | 114 | ///////***CallbackBuilder***////// 115 | public final CallbackBuilder callbackBuilder() { 116 | return operator.getCallbackBuilder() != null ? operator.getCallbackBuilder() : new CallbackBuilder(); 117 | } 118 | ///////***CallbackBuilder***////// 119 | ///////***public业务方法***////// 120 | 121 | /** 122 | *
{@link #callbackBuilder()}: 获取控件的回调构造类{@link CallbackBuilder} 123 | *
{@link #loadComplete(AbstractCommentModel model)}: 首次加载完成数据后调用 124 | *
{@link #loadFailed(boolean)}: 首次加载出现错误时调用,可以控制是否显示错误视图 125 | *
{@link #refreshComplete(AbstractCommentModel model)}: 刷新数据完成后调用 126 | *
{@link #refreshFailed(String, boolean)}: 刷新出现错误时调用,可以控制是否显示错误视图 127 | *
{@link #loadMoreComplete(AbstractCommentModel model)}: 上拉加载更多数据完成后调用 128 | *
{@link #loadMoreFailed(String, boolean)}: 上拉加载更多数据出现错误时调用,可以控制是否显示错误视图 129 | *
{@link #loadMoreReplyComplete(AbstractCommentModel model)}: 加载更多回复数据完成后调用 130 | *
{@link #loadMoreReplyFailed(String, boolean)}: 加载更多回复数据出现错误时调用,可以控制是否显示错误视图 131 | *
{@link #setEmptyView(View)}: 设置数据为空时的空数据视图 132 | *
{@link #setErrorView(View)}: 设置加载失败的使用的错误视图 133 | *
{@link #setViewStyleConfigurator(ViewStyleConfigurator)}: 设置控件样式配置器,控件默认使用默认样式配置器 134 | * {@link com.jidcoo.android.widget.commentview.defaults.DefaultViewStyleConfigurator}, 135 | * 如果自定义样式配置器,请继承自{@link ViewStyleConfigurator},自定义样式配置器可参考默认样式配置器 136 | * {@link com.jidcoo.android.widget.commentview.defaults.DefaultViewStyleConfigurator} 137 | *
{@link #getCommentList()}: 获取评论数据集合 138 | *
{@link #getReplyList(int position)}:根据父级评论的位置获取父级评论回复的集合 139 | *
{@link #addComment(CommentEnable)}:添加一条评论 140 | *
{@link #addReply(ReplyEnable, int)}:给所在评论中添加一条回复 141 | *
{@link #addHeaderView(View, boolean)}:添加头部布局 142 | *
{@link #removeHeaderView(View)}:移除头部布局
143 | */
144 | public void loadComplete(AbstractCommentModel model) {
145 | operator.load(model);
146 | }
147 |
148 | public void loadFailed(boolean isShowErrorView) {
149 | operator.error(4, null, isShowErrorView);
150 | }
151 |
152 | ;
153 |
154 | public void refreshComplete(AbstractCommentModel model) {
155 | operator.refreshComplete(model);
156 | }
157 |
158 | public void refreshFailed(String msg, boolean isShowErrorView) {
159 | operator.error(1, msg, isShowErrorView);
160 | }
161 |
162 | ;
163 |
164 | public void loadMoreComplete(AbstractCommentModel model) {
165 | operator.loadMoreComplete(model);
166 | }
167 |
168 | public void loadMoreFailed(String msg, boolean isShowErrorView) {
169 | operator.error(2, msg, isShowErrorView);
170 | }
171 |
172 | ;
173 |
174 | public void loadMoreReplyComplete(AbstractCommentModel model) {
175 | operator.loadMoreReplyComplete(model);
176 | }
177 |
178 | public void loadMoreReplyFailed(String msg, boolean isShowErrorView) {
179 | operator.error(3, msg, isShowErrorView);
180 | }
181 |
182 | ;
183 |
184 | public void setEmptyView(View view) {
185 | operator.setEmptyView(view);
186 | }
187 |
188 | public void setErrorView(View view) {
189 | operator.setErrorView(view);
190 | }
191 |
192 | public void addHeaderView(View view, boolean canClickable) {
193 | operator.addHeaderView(view, canClickable);
194 | }
195 |
196 | public void removeHeaderView(View view) {
197 | operator.removeHeaderView(view);
198 | }
199 |
200 | public void setViewStyleConfigurator(ViewStyleConfigurator styleConfigurator) {
201 | operator.setViewStyleConfigurator(styleConfigurator);
202 | }
203 |
204 | ;
205 |
206 | public List extends CommentEnable> getCommentList() {
207 | return operator.getComment();
208 | }
209 |
210 | public List extends ReplyEnable> getReplyList(int position) {
211 | return operator.getReplies(position);
212 | }
213 |
214 | public
19 | * 1、自定义布局xml中最外层布局必须是LinearLayout并且把最外层布局id设置为reply_rootView
20 | * ViewHolder:
21 | * 1、在buildReplyItem()中自定义布局初始化时,必须使用ViewHolder机制
22 | * 2、初始化过程中,自定义Holder必须继承自com.jidcoo.android.widget.commentview.view.ViewHolder,查看{@link ViewHolder}
23 | *
24 | * @author Jidcoo
25 | */
26 | public interface CustomReplyItemCallback 评论布局无特殊要求,可根据需要实现 一个Model实例含有n条母数据 每1条母数据(评论)携带m条子数据(评论的回复) 模型结构:
22 | * 支持Comment、Reply自定义数据类型: 自定义数据类型必须继承自抽象类AbstractCommentModel,查看{@link AbstractCommentModel} 可自定义数据类型,但必须实现CommentEnable接口,如下: 相当于getView的逻辑 如果使用自定义布局,需要实现CustomCommentItemCallback、CustomReplyItemCallback接口 自定义评论布局,查看{@link CustomCommentItemCallback} 自定义回复布局,查看{@link CustomReplyItemCallback} 此类可作为自定义回复布局ViewHolder的模板 注意: 自定义回复布局ViewHolder必须继承自ViewHolder,查看{@link ViewHolder} 此配置器为标准模板 自定义样式配置器必须继承自ViewStyleConfigurator,查看{@link ViewStyleConfigurator} 样式变量说明,请查看{@link ViewStyleConfigurator} 实际上,自定义样式配置器可以直接复制本类,然后再根据具体把样式修改就好了 自定义评论模型抽象类 设置样式配置器 该样式配置器针对非自定义控件的样式的具体配置 可根据具体需求配置这部分的控件的样式 自定义样式配置器必须继承自ViewStyleConfigurator,查看{@link ViewStyleConfigurator}
10 | *
12 | *
13 | * @author Jidcoo
14 | */
15 | public abstract class ViewHolder {
16 | /**
17 | * 自定义布局这个view必须为非空
18 | */
19 | public LinearLayout rootView;
20 |
21 | public ViewHolder(View view) {
22 | try {
23 | rootView = view.findViewById(R.id.reply_rootView);
24 | } catch (Exception e) {
25 | throw new RuntimeException("If you use a custom layout, the outermost layout must be a LinearLayout, and you need to set its id attribute value to \"reply_rootView\"");
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/commentview/src/main/java/com/jidcoo/android/widget/commentview/view/ViewStyleConfigurator.java:
--------------------------------------------------------------------------------
1 | package com.jidcoo.android.widget.commentview.view;
2 |
3 | import android.graphics.Typeface;
4 |
5 |
6 | /**
7 | * 非可自定义控件样式配置器
8 | * 该样式配置器针对非自定义控件的样式的具体配置 可根据具体需求配置这部分的控件的样式 自定义样式配置器必须继承自本类 1、refreshViewColor 类型:String 说明:下拉刷新后出现的圆形滚动条的颜色 赋值样例:#000000 2、lmv_showText(正常显示状态) 类型:String 说明:当回复数据Item可以加载更多(分页加载)时,在最后一条回复Item的View下面显示的文字 赋值样例:展开更多回复 3、lmv_textSize 类型:int 说明:第二条说明中的文字大小 赋值样例:14 4、lmv_textColor 类型:String 说明:第二条说明中的文字颜色 赋值样例:#000000 5、lmv_textStyle 类型:Typeface,查看{@link Typeface} 说明:第二条说明中的文字样式(正常、斜体、加粗) 赋值样例:Typeface.defaultFromStyle(Typeface.NORMAL) 6、lmv_loading_showText(加载中状态) 类型:String 说明:当回复数据Item可以加载更多(分页加载)时,在最后一条回复Item的加载更多View被点击后显示的文字 赋值样例:加载中 7、lmv_loading_textSize 类型:int 说明:第六条说明中的文字大小 赋值样例:14 8、lmv_loading_textColor 类型:String 说明:第六条说明中的文字颜色 赋值样例:#000000 9、lmv_loading_textStyle 类型:Typeface,查看{@link Typeface} 说明:第六条说明中的文字样式(正常、斜体、加粗) 赋值样例:Typeface.defaultFromStyle(Typeface.NORMAL) 10、lmv_loading_progressBarColor 类型:String 说明:当最后一条回复ItemView的可加载更多View状态为正在加载状态时,
52 | * 第六条说明中的文字右边会显示一个圆形progressBar以增强UI加载效果,
53 | * 该属性是这个progressBar的颜色值 赋值样例:#000000 11、lmv_loading_progressBarSize 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十条说明中的progressBar控件的大小尺寸 赋值样例:ViewUtil.dpToPx(14) 12、lmv_adjustMargins 类型:Boolean(默认为false) 说明:是否调整最后一条回复Item的加载更多View的边距,如果自定义回复布局,可能需要
62 | * 调整这个View的边距来使布局更美观,一般情况下都需要调整边距,所以这个属性一般都为true 赋值样例:true 13、lmv_adjustMarginsLeft 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十二条说明中的view的左边距,如果lmv_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 14、lmv_adjustMarginsTop 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十二条说明中的view的上边距,如果lmv_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 15、lmv_adjustMarginsRight 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十二条说明中的view的右边距,如果lmv_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 16、lmv_adjustMarginsBottom 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十二条说明中的view的下边距,如果lmv_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 17、dividerColor 类型:String 说明:控件Item的分割线颜色(包含一级分割线和二级分割线) 赋值样例:#000000 18、dividerHeight 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:控件Item的分割线高度(包含一级分割线和二级分割线) 赋值样例:ViewUtil.dpToPx(1),高度一般为1dp 19、isDrawChildDivider 类型:Boolean(默认为false) 说明:是否绘制某一条评论下的最后一条回复Item与下一条评论的Item的分割线,默认不绘制,
91 | * 可根据具体需要选择是否绘制 赋值样例:true 20、c_divider_adjustMargins 类型:Boolean(默认为false) 说明:是否调整第十七条说明中的分割线的边距,如果isDrawDivider为false,则此属性无效。
96 | * 因为第十九条说明中的分割线宽度固定为match_parent(即铺满全屏),但是可以通过调整分割线的边距
97 | * 来间接调整分割线的宽度和位置,可根据具体需要选择是否调整分割线的边距 赋值样例:true 21、c_divider_adjustMarginsLeft 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十九条说明中的分割线的左边距,如果divider_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(1) 22、c_divider_adjustMarginsTop 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十九条说明中的分割线的上边距,如果divider_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(1) 23、c_divider_adjustMarginsRight 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十九条说明中的分割线的右边距,如果divider_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(1) 24、c_divider_adjustMarginsBottom 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第十九条说明中的分割线的下边距,如果divider_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(1) 25、f_divider_adjustMargins 类型:Boolean(默认为false) 说明:是否调整评论item的分割线的边距 赋值样例:true 26、f_divider_adjustMarginsLeft 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:评论item的分割线的左边距 赋值样例:ViewUtil.dpToPx(1) 27、f_divider_adjustMarginsTop 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:评论item的分割线的上边距 赋值样例:ViewUtil.dpToPx(1) 28、f_divider_adjustMarginsRight 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:评论item的分割线的右边距 赋值样例:ViewUtil.dpToPx(1) 29、f_divider_adjustMarginsBottom 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:评论item的分割线的下边距 赋值样例:ViewUtil.dpToPx(1) 30、lm_footerProgressBarSize 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:上拉刷新时,控件底部会有一个圆形ProgressBar来增加加载中的UI效果,此属性为ProgressBar的大小 赋值样例:ViewUtil.dpToPx(1) 31、lm_footerProgressBarColor 类型:String 说明:第三十条说明中的ProgressBar的颜色 赋值样例:#000000 32、lm_footerProgressBar_adjustMargins 类型:Boolean(默认为false) 说明:是否调整第三十条说明中的ProgressBar的边距 赋值样例:true 33、lm_footerProgressBar_adjustMarginsLeft 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第三十条说明中的ProgressBar的左边距,如果lm_footerProgressBar_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 34、lm_footerProgressBar_adjustMarginsTop 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第三十条说明中的ProgressBar的上边距,如果lm_footerProgressBar_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 35、lm_footerProgressBar_adjustMarginsRight 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第三十条说明中的ProgressBar的右边距,如果lm_footerProgressBar_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 36、lm_footerProgressBar_adjustMarginsBottom 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第三十条说明中的ProgressBar的下边距,如果lm_footerProgressBar_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 37、lm_footer_text 类型:String 说明:当所有数据加载完成后控件底部textView显示的文字 赋值样例:哈哈,所有评论都在这了 38、lm_footer_textColor 类型:String 说明:第三十七条说明中的textView文字的颜色 赋值样例:#666666 39、lm_footer_textSize 类型:int 说明:第三十七条说明中的textView文字的大小 赋值样例:14 40、lm_footer_textStyle 类型:Typeface 说明:第三十七条说明中的textView文字的样式(正常,斜体、加粗) 赋值样例:Typeface.defaultFromStyle(Typeface.NORMAL) 41、lm_footer_text_adjustMargins 类型:Boolean(默认为false) 说明:是否调整第三十七条说明中的textView的边距 赋值样例:true 42、lm_footer_text_adjustMarginsLeft 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第三十七条说明中的textView的左边距,如果lm_footer_text_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 43、lm_footer_text_adjustMarginsTop 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第三十七条说明中的textView的上边距,如果lm_footer_text_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 44、lm_footer_text_adjustMarginsRight 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第三十七条说明中的textView的右边距,如果lm_footer_text_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14) 45、lm_footer_text_adjustMarginsBottom 类型:int(要求单位:px,因为需要把(dp/dip值转换为px值)) 说明:第三十七条说明中的textView的下边距,如果lm_footer_text_adjustMargins为false,则此属性无效 赋值样例:ViewUtil.dpToPx(14)
18 | * 布局:默认评论回复的分页数据模型
13 | * {@link PagerEnable}分页模型
14 | *
--->Comment(Size=n)【评论】
19 | *
--->Reply(Size=m)【回复】
20 | *
-------------------------------
21 | *
9 | * AbstractCommentModel中传入的泛型
5 | *
6 | * 在Android端只实现为对分页数据的Get/Set操作
7 | *
8 | * 具体的分页逻辑应该由后端完成,客户端只负责对数据的处理
9 | *
10 | *
11 | * @author Jidcoo
12 | */
13 | public class PagerEnable {
14 | /**
15 | * 当前页码
16 | */
17 | public int currentPage;
18 | /**
19 | * 每一页数据的大小
20 | */
21 | private int pageSize;
22 | /**
23 | * 总页数
24 | */
25 | public int totalPages;
26 | /**
27 | * 数据总数
28 | */
29 | public int totalDataSize;
30 | /**
31 | * 下一个页码
32 | */
33 | public int nextPage;
34 | /**
35 | * 上一个页码
36 | */
37 | public int prefPage;
38 |
39 | public int getCurrentPage() {
40 | return currentPage;
41 | }
42 |
43 | public void setCurrentPage(int currentPage) {
44 | this.currentPage = currentPage;
45 | }
46 |
47 | public int getPageSize() {
48 | return pageSize;
49 | }
50 |
51 | public void setPageSize(int pageSize) {
52 | this.pageSize = pageSize;
53 | }
54 |
55 | public int getTotalPages() {
56 | return totalPages;
57 | }
58 |
59 | public void setTotalPages(int totalPages) {
60 | this.totalPages = totalPages;
61 | }
62 |
63 | public int getTotalDataSize() {
64 | return totalDataSize;
65 | }
66 |
67 | public void setTotalDataSize(int totalDataSize) {
68 | this.totalDataSize = totalDataSize;
69 | }
70 |
71 | public int getNextPage() {
72 | return nextPage;
73 | }
74 |
75 | public void setNextPage(int nextPage) {
76 | this.nextPage = nextPage;
77 | }
78 |
79 | public int getPrefPage() {
80 | return prefPage;
81 | }
82 |
83 | public void setPrefPage(int prefPage) {
84 | this.prefPage = prefPage;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/commentview/src/main/java/com/jidcoo/android/widget/commentview/model/ReplyEnable.java:
--------------------------------------------------------------------------------
1 | package com.jidcoo.android.widget.commentview.model;
2 |
3 |
4 | /**
5 | * 自定义评论模型必须继承自此类
6 | *
7 | * @author Jidcoo
8 | */
9 | public class ReplyEnable {
10 | }
11 |
--------------------------------------------------------------------------------
/commentview/src/main/java/com/jidcoo/android/widget/commentview/operator/AbsAdapterOperator.java:
--------------------------------------------------------------------------------
1 | package com.jidcoo.android.widget.commentview.operator;
2 |
3 | import com.jidcoo.android.widget.commentview.model.CommentEnable;
4 | import com.jidcoo.android.widget.commentview.model.ReplyEnable;
5 | import com.jidcoo.android.widget.commentview.view.CommentListView;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Adapter业务抽象类,抽取出来方便维护
11 | * 具体实现类AdapterOperator,查看{@link AdapterOperator}
12 | * 泛型C是评论数据模型
13 | *
14 | * @author Jidcoo
15 | */
16 | public abstract class AbsAdapterOperator
11 | * 在自定义回复布局中最外层必须使用LinearLayout并将布局id设置为“reply_rootView”,否则会报错。
12 | * 样式变量说明:
13 | *
200 | *
201 | * @author Jidcoo
202 | */
203 | public abstract class ViewStyleConfigurator {
204 | /**
205 | * 下拉刷新控件颜色
206 | */
207 | public String refreshViewColor;
208 |
209 | //*********//回复加载更多控件样式//*************//
210 | //Part1//
211 | public String lmv_showText;
212 | public int lmv_textSize;
213 | public String lmv_textColor;
214 | public Typeface lmv_textStyle;
215 | //Part2//
216 | public String lmv_loading_showText;
217 | public int lmv_loading_textSize;
218 | public String lmv_loading_textColor;
219 | public Typeface lmv_loading_textStyle;
220 | public String lmv_loading_progressBarColor;
221 | public int lmv_loading_progressBarSize;
222 | //Part3//
223 | public boolean lmv_adjustMargins;
224 | public int lmv_adjustMarginsLeft;//dp
225 | public int lmv_adjustMarginsTop;//dp
226 | public int lmv_adjustMarginsRight;//dp
227 | public int lmv_adjustMarginsBottom;//dp
228 | //*********//回复加载更多控件样式//*************//
229 |
230 | //*********//分割线总样式//*************//
231 | public String dividerColor;
232 | public int dividerHeight;//dp
233 | //*********//分割线总样式//*************//
234 |
235 | //*********//回复Item最后一项的下划线(分样式)//*************//
236 | public boolean isDrawChildDivider;
237 | public boolean c_divider_adjustMargins;
238 | public int c_divider_adjustMarginsLeft;//dp
239 | public int c_divider_adjustMarginsTop;//dp
240 | public int c_divider_adjustMarginsRight;//dp
241 | public int c_divider_adjustMarginsBottom;//dp
242 | //*********//回复Item最后一项的下划线(分样式)//*************//
243 |
244 |
245 | //*********//评论Item的分割线(分样式)//*************//
246 | /**
247 | * 评论Item的分割线颜色、高度与回复Item的分割线一样
248 | */
249 | public boolean f_divider_adjustMargins;
250 | public int f_divider_adjustMarginsLeft;//dp
251 | public int f_divider_adjustMarginsTop;//dp
252 | public int f_divider_adjustMarginsRight;//dp
253 | public int f_divider_adjustMarginsBottom;//dp
254 | //*********//评论Item的分割线(分样式)//*************//
255 |
256 | //*********//底部上拉加载更多圆形ProgressBar的大小和颜色//*************//
257 | public int lm_footerProgressBarSize = 12;//dp
258 | public String lm_footerProgressBarColor;
259 | public boolean lm_footerProgressBar_adjustMargins;
260 | public int lm_footerProgressBar_adjustMarginsLeft;//dp
261 | public int lm_footerProgressBar_adjustMarginsTop;//dp
262 | public int lm_footerProgressBar_adjustMarginsRight;//dp
263 | public int lm_footerProgressBar_adjustMarginsBottom;//dp
264 | //*********//底部上拉加载更多圆形ProgressBar的大小和颜色//*************//
265 |
266 |
267 | //*********//底部上拉加载更多完成后的textView//*************//
268 | //文本,颜色、大小、样式、边距
269 | public String lm_footer_text;
270 | public String lm_footer_textColor;
271 | public int lm_footer_textSize = 12;
272 | public Typeface lm_footer_textStyle;
273 | public boolean lm_footer_text_adjustMargins;
274 | public int lm_footer_text_adjustMarginsLeft;//dp
275 | public int lm_footer_text_adjustMarginsTop;//dp
276 | public int lm_footer_text_adjustMarginsRight;//dp
277 | public int lm_footer_text_adjustMarginsBottom;//dp
278 | //*********//底部上拉加载更多完成后的textView//*************//
279 |
280 | }
281 |
--------------------------------------------------------------------------------
/commentview/src/main/res/drawable/ico.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jidcoo/CommentView/26df8f9903d0dd664bc975945b17faba2b3fba73/commentview/src/main/res/drawable/ico.png
--------------------------------------------------------------------------------
/commentview/src/main/res/drawable/pxjh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jidcoo/CommentView/26df8f9903d0dd664bc975945b17faba2b3fba73/commentview/src/main/res/drawable/pxjh.png
--------------------------------------------------------------------------------
/commentview/src/main/res/layout/commentview.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |