Как создать модель для комментариев?

#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();
}