在我的应用程序中,我必须获取已接收消息的列表,这些消息存储在服务器的json响应中。现在,我为此目的创建了几个类:
1)我的界面:
@Headers({"Content-type: application/json"})
@GET("/v1/message/list")
Call<MessageArray> getInMess(@Header("Authorization") String token, @Query("type") int type, @Query("offset") int offset);
2)一条消息的类别:
public class Message {
private int id;
private String subject;
private boolean can_delete;
@SerializedName("new") //this is because new is a protected keyword. this annotation is for Gson parsing library. Any library has his own annotation
private int newField;
private String date;
private String receiver_name;
private String sender_name;
public Message() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public boolean isCan_delete() {
return can_delete;
}
public void setCan_delete(boolean can_delete) {
this.can_delete = can_delete;
}
public int getNewField() {
return newField;
}
public void setNewField(int newField) {
this.newField = newField;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getReceiver_name() {
return receiver_name;
}
public void setReceiver_name(String receiver_name) {
this.receiver_name = receiver_name;
}
public String getSender_name() {
return sender_name;
}
public void setSender_name(String sender_name) {
this.sender_name = sender_name;
}
}
3)消息数组:
public class MessageArray {
private int count;
private List<Message> messages;
private String next_url;
private String previous_url;
public MessageArray() {
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(List<Message> messages) {
this.messages = messages;
}
public String getNext_url() {
return next_url;
}
public void setNext_url(String next_url) {
this.next_url = next_url;
}
public String getPrevious_url() {
return previous_url;
}
public void setPrevious_url(String previous_url) {
this.previous_url = previous_url;
}
}
4)回复样本:
HTTP 200
{
"count": int, # number of messages
"messages": [ # array of messages
{
"id": int, # message id
"subject": str, # message subject
"can_delete": bool, # can it be deleted (True) or not (False)
"new": int # message already read (0) or not (1)
"date": str, # date of message in 'd.m.y'. If message was sent today format will be 'H:M'
"receiver_name": str, # name of receiver if type=1
"sender_name": str, # name of sender if type=0
}, ...
],
"next_url": URL, # url for get next messages, if no more messages value is null
"previous_url": URL # url for get previous messages, if no more messages value is null
}
我决定使用RecyclerView,因为它比ListView更完美,因此我为其创建了类适配器:
class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder>
{
private List<Message> messageList;
private Context ctx;
public MessageAdapter(List<Message> messageList, Context ctx) {
this.messageList = messageList;
this.ctx = ctx;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_of_rec_m, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Message message = messageList.get(position);
holder.subject.setText(message.getSubject());
holder.from.setText(message.getSender_name());
}
@Override
public int getItemCount() {
return messageList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
final TextView from,subject;
ViewHolder(View v) {
super(v);
subject = v.findViewById(R.id.subject);
from = v.findViewById(R.id.from);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
}
}
但是现在我不知道如何初始化这个recycleView。我有这样的片段类:
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_received, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
/* recyclerView = view.findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));*/
received();
}
public void received() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://server/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
adapter = null;
//recyclerView.setAdapter(adapter);
tok_pref = Objects.requireNonNull(getActivity()).getSharedPreferences(ACCESS_TOKEN,Context.MODE_PRIVATE);
String access_token = tok_pref.getString(ACCESS_TOKEN,"");
final APIService mAPIService = retrofit.create(APIService.class);
mAPIService.getInMess("Bearer " + access_token, 0, 1).enqueue(new Callback<MessageArray>() {
@Override
public void onResponse(@NonNull Call<MessageArray> call, @NonNull Response<MessageArray> response) {
if (response.isSuccessful()) {
/* messageArrayList = (ArrayList<Message>) response.body().getMessages();
adapter = new MessageAdapter(messageArrayList, getActivity());
recyclerView.setAdapter(adapter);*/
}
}
@Override
public void onFailure(@NonNull Call<MessageArray> call, @NonNull Throwable t) {
}
});
}
我的logcat响应样本:
{"count": 3, "next_url": null, "previous_url": null, "messages": [{"new": 0, "sender_name": "Poltava - Amina Al-Shahoud", "attach": false, "subject": "\u0441\u0430\u0432\u0441\u0432\u0430 \u0432\u044b\u043c\u0430\u0432", "id": 2409277, "date": "25.07.18", "can_delete": true}, {"new": 0, "sender_name": "Poltava - Amina Al-Shahoud", "attach": false, "subject": "\u043f\u0440\u0435\u0432\u0435\u0434", "id": 2409276, "date": "25.07.18", "can_delete": true}, {"new": 0, "sender_name": "Poltava - Amina Al-Shahoud", "attach": false, "subject": "AW: Neu registrierte/r Bewerber/in Andrew Horoshko (ID 9533961) in Ihrer Vermittlungsdokumentation", "id": 2407651, "date": "19.07.18", "can_delete": true}]}
我最后的错误:
08-03 04:45:26.112 3978-3978/com.example.developer_4.test_login E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.developer_4.test_login, PID: 3978
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setHasFixedSize(boolean)' on a null object reference
at com.example.developer_4.test_login.Tabs.Received.onCreateView(Received.java:46)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2425)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2623)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2410)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2365)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2242)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:654)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:168)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1244)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1092)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1622)
at android.view.View.measure(View.java:19857)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:733)
at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:95)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1536)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:803)
at android.view.View.measure(View.java:19857)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1121)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:689)
at android.view.View.measure(View.java:19857)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2275)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1366)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1619)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
我希望你能帮助我解决我的问题。谢谢您的好建议和答案。
答案 0 :(得分:1)
删除onViewCreated
,然后在onCreateView
中添加以下内容
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_received, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));*/
received();
return rootView;
}
还尝试为@SerializedName
添加Message
注释
public class Message {
@SerializedName("new")
@Expose
private Integer _new;
@SerializedName("sender_name")
@Expose
private String senderName;
@SerializedName("attach")
@Expose
private Boolean attach;
@SerializedName("subject")
@Expose
private String subject;
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("date")
@Expose
private String date;
@SerializedName("can_delete")
@Expose
private Boolean canDelete;
public Integer getNew() {
return _new;
}
public void setNew(Integer _new) {
this._new = _new;
}
public String getSenderName() {
return senderName;
}
public void setSenderName(String senderName) {
this.senderName = senderName;
}
public Boolean getAttach() {
return attach;
}
public void setAttach(Boolean attach) {
this.attach = attach;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Boolean getCanDelete() {
return canDelete;
}
public void setCanDelete(Boolean canDelete) {
this.canDelete = canDelete;
}
}
和MessageArray
public class MessageArray {
@SerializedName("count")
@Expose
private Integer count;
@SerializedName("next_url")
@Expose
private Object nextUrl;
@SerializedName("previous_url")
@Expose
private Object previousUrl;
@SerializedName("messages")
@Expose
private List<Message> messages = null;
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public Object getNextUrl() {
return nextUrl;
}
public void setNextUrl(Object nextUrl) {
this.nextUrl = nextUrl;
}
public Object getPreviousUrl() {
return previousUrl;
}
public void setPreviousUrl(Object previousUrl) {
this.previousUrl = previousUrl;
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(List<Message> messages) {
this.messages = messages;
}
}