#android
#Android
Вопрос:
Привет, веб-API выдает мне следующий JSON. Это для комментариев.
{
"comment_count": 9,
"comments": [
{
"comment_ID": "2",
"comment_post_ID": "167",
"comment_author": "admin",
"comment_author_email": "xxxx@gmail.com",
"comment_author_url": "",
"comment_author_IP": "::1",
"comment_date": "2019-01-21 10:45:59",
"comment_date_gmt": "2019-01-21 02:45:59",
"comment_content": "asdada asda sda sd asdsada sd as",
"comment_karma": "0",
"comment_approved": "1",
"comment_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"comment_type": "",
"comment_parent": "0",
"user_id": "1",
"like_cnt": "1",
"image": "",
"author_image": "52263886_2292810744295258_5904172631346642944_n-150x150.jpg",
"is_liked": true
},
{
"comment_ID": "3",
"comment_post_ID": "167",
"comment_author": "admin",
"comment_author_email": "xxxx@gmail.com",
"comment_author_url": "",
"comment_author_IP": "::1",
"comment_date": "2019-01-21 11:12:37",
"comment_date_gmt": "2019-01-21 03:12:37",
"comment_content": "a",
"comment_karma": "0",
"comment_approved": "1",
"comment_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"comment_type": "",
"comment_parent": "0",
"user_id": "1",
"like_cnt": "0",
"image": "",
"author_image": "52263886_2292810744295258_5904172631346642944_n-150x150.jpg",
"is_liked": false
}
]
}
Уровни ответов на комментарии не ограничены. Она может быть многоуровневой. Но я хочу сделать это как раздел комментариев facebook. Что означает:
A: comment - level 0
B: comment - level 0
C: reply of comment B - level 1
D: reply of comment C - level 2
Уровень комментария D равен 2. Комментарий D — это ответ на комментарий C.
Я хочу отметить имя автора комментария C в комментарии D. Потому что я не хочу добавлять уровень 2.
Но как мне сохранить данные в адаптере? Как вы можете видеть, здесь нет уровня. Пока что я написал: / Отредактировано/
for(int i = 0; i < result.getComments().size(); i ){
Comment comment = result.getComments().get(i);
if(comment.getComment_parent().equals("0")) continue;
String parentId = comment.getComment_parent();
boolean parentFound = false;
boolean rootFound = false;
while(!parentFound || !rootFound){
int parentPosition = binarySearch(result.getComments(),0, result.getComments().size(), parentId);
if(parentPosition == -1) break;
Comment temp = result.getComments().get(parentPosition);
if(temp.getComment_ID().equals(parentId)){
if (!parentFound){
parentFound = true;
comment.setTag(temp.getComment_author());
}
if (temp.getComment_parent().equals("0")) {
rootFound = true;
comment.setRootId(temp.getComment_ID());
temp.addChildComment(comment);
} else {
parentId = temp.getComment_parent();
}
}
}
}
Iterator itr = result.getComments().iterator();
while (itr.hasNext()) {
Comment comment = (Comment) itr.next();
if(!comment.getComment_parent().equals("0")){
itr.remove();
}
}
private int binarySearch(List<Comment> arr, int l, int r, String x)
{
if (r>=l)
{
int mid = l (r - l)/2;
if (arr.get(mid).getComment_ID().equals(x))
return mid;
if (Integer.valueOf(arr.get(mid).getComment_ID()) > Integer.valueOf(x))
return binarySearch(arr, l, mid-1, x);
return binarySearch(arr, mid 1, r, x);
}
return -1;
}
комментарий публичного класса {
private String comment_ID;
private String comment_post_ID;
private String comment_author;
private String comment_author_email;
private String comment_author_url;
private String comment_author_IP;
private String comment_date;
private String comment_date_gmt;
private String comment_content;
private String comment_karma;
private String comment_approved;
private String comment_agent;
private String comment_type;
private String comment_parent;
private String user_id;
private boolean isSend = true;
private List<Comment> commentList;
private String rootId;
private String tag;
Комментарии:
1. Ваш код прямо сейчас находит только комментарии, у которых нет родительского элемента. Теперь вы можете выполнить итерацию в комментариях, у которых есть родительские элементы, проверить, присутствуют ли они в первом массиве, и это будет ваш массив «комментариев 1-го уровня». Промойте и повторите. Будьте осторожны, это может привести к проблемам с производительностью на очень больших объемах данных.
2. Не анализируйте комментарии, когда вы их получите. Например, сохранить «comment_count»: и «comments» как строковый элемент POJO, это означает анализировать «comments» как строку, а не как фактический объект. Теперь проверьте, больше ли «comment_count» НУЛЯ, затем вручную проанализируйте значение «comments». Таким образом, вы можете устранить комментарии на уровне mutilevel.
Ответ №1:
Не создавайте класс модели вручную, я предложу вам создать классы модели / POJO с помощью генератора ROBOPOJO, он сгенерирует все классы модели для вас, вам не нужно создавать это самостоятельно, также поможет вам в будущем при создании класса модели. Для этого просто нужна строка JSON, и щелчок сделает вашу работу выполненной
Ответ №2:
Просто используйте инструмент преобразования jsonschema2pojo, чтобы получить ваш обычный старый Java-объект. Это даст вам очень эффективный объект данных в соответствии с вашим ответом API, который вы можете дополнительно расширить с помощью любой требуемой логики в вашем приложении.
Ответ №3:
вы должны создать 2 класса — один для модификации для анализа ответа WebAPI и Comment
саму сущность.
Ниже приведен класс для модифицированного ответа:
public class Comments{
@SerializedName("comment_count")
private int commentCount; //this could be ignored
private List<Comment> comments;
}
@SerializedName("comment_count")
сообщает изменить ключ JSON на commentCount
поле, без этой аннотации вы должны объявить поле с тем же именем, что и ключ JSON, например private int comment_count;
Сам объект комментария:
public class Comment {
private String comment_ID;
private String comment_post_ID;
private String comment_author;
private String comment_author_email;
private String comment_author_url;
private String comment_author_IP;
private String comment_date;
private String comment_date_gmt;
private String comment_content;
private String comment_karma;
private String comment_approved;
private String comment_agent;
private String comment_type;
private String comment_parent;
private String user_id;
private boolean isSend = true;
}
Вам не нужно самостоятельно анализировать ответ, позвольте этой работе быть выполненной с помощью Retrofit, и вы получите List<Comment>
который вы могли бы использовать для свободного заполнения вашего адаптера или сохранения этого массива в БД.
Ниже показано, как получить ответ с помощью Retrofit. Где-то в вашем коде вы вызываете метод
private void requestComments() {
ApiManager.getCommentsAdapter().getComments(new IApiCallBackSuccess<Comments>() {
@Override
public void onApiSuccess(Comments response) {
onGotComments(response); // do there whatever you like
}
}, this);
}
в APIManager:
public final class ApiManager {
public static CommentsApiAdapter getCommentsAdapter() {
return new CommentsApiAdapter();
}
}
CommentsApiAdapter:
public class CommentsApiAdapter extends MyApiAdapter<CommentsApiService> {
@Override
Class<CommentsApiService> provideServiceClass() {
return CommentsApiService.class;
}
public void getComments(final IApiCallBackSuccess<Comments> callBackSuccess,
final IApiCallBackError callBackError) {
getService().getComments().enqueue();
}
}
MyApiAdapter, ApiUrlHelper.BASE_URL — это просто статическая конечная строка с базовым URL типа «www.mywebapi.com «
public abstract class MyApiAdapter<ApiService> extends BaseApiAdapter<ApiService> {
@Override
String getBaseUrl() {
return ApiUrlHelper.BASE_URL;
}
}
CommentsApiService (представляющий службу модернизации)
public interface CommentsApiService {
@GET("/api/comments")
Call<Comments> getComments();
}
BaseApiAdapter
abstract class BaseApiAdapter<ApiService> {
private final int TIME_OUT = ApiUrlHelper.TIME_OUT;
private final ApiService mApiService;
private final Gson mGson;
BaseApiAdapter() {
final OkHttpClient.Builder okClientBuilder = new OkHttpClient.Builder()
.connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
.readTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
.writeTimeout(TIME_OUT, TimeUnit.MILLISECONDS);
mGson = gsonBuilder.create();
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(getBaseUrl())
.addConverterFactory(GsonConverterFactory.create(mGson))
.client(okClientBuilder.build())
.build();
mApiService = retrofit.create(provideServiceClass());
}
abstract Class<ApiService> provideServiceClass();
}