【发布时间】:2018-07-31 13:34:04
【问题描述】:
长期以来,我一直在尝试修复我的代码。我找了很多地方找到解决方案,但无济于事。如果您查看我的代码并告诉我为什么 RecylerView 中的 TextViews 没有显示,那就太好了。
我正在尝试使用 WebSocket-ing 并从 Internet 获取数据。这应该以不断更新的方式显示在 RecyclerView 中。来自涟漪服务器的数据分类账自然会延迟。我想在 RecyclerView 中展示它们的某些方面。所有的 TextView 都可以改变内容,他们只是尝试一下。
这是我的 WebSocketActivity 代码:
package com.example.menes.searchcode.Websocketing;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.example.menes.searchcode.R;
import com.google.gson.Gson;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONObject;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class WebSocketActivity extends AppCompatActivity implements MyWebSocketAdapter.OnItemClickListener {
private RecyclerView webSocketRecyclerView;// = findViewById(R.id.myRecyclerView);
private MyWebSocketAdapter myWebSocketAdapter;
List<LedgerResult> adapterLedgerResultList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.websocket_and_button_thing);
Button startWebsocketButton = findViewById(R.id.startButton);
final Button stopWebSocketButton = findViewById(R.id.stopButton);
startWebsocketButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if(adapterLedgerResultList.size() == 0)
Toast.makeText(WebSocketActivity.this,"Yes it is empty!, nice.",Toast.LENGTH_SHORT).show();
myWebSocketAdapter = new MyWebSocketAdapter(WebSocketActivity.this, adapterLedgerResultList);
webSocketRecyclerView = findViewById(R.id.myRecyclerView);
webSocketRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
webSocketRecyclerView.setAdapter(myWebSocketAdapter);
final MySimpleClient c = new MySimpleClient( new URI( "wss://s2.ripple.com:443" ));
c.connect();
stopWebSocketButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
c.close();
}
});
} catch (URISyntaxException e){
e.printStackTrace();
Toast.makeText(WebSocketActivity.this,"URISyntaxException occurred. Try again!",Toast.LENGTH_SHORT).show();
}
}
});
}
public void bindIt () {
//webSocketRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
myWebSocketAdapter.setOnItemClickListener(this);
webSocketRecyclerView.setHasFixedSize(true);
//webSocketRecyclerView.setAdapter(myWebSocketAdapter);
}
@Override
public void onItemClick(int position) {
Intent intent = new Intent(this, LedgerDisplayActivity.class);
intent.putExtra("id", adapterLedgerResultList.get(position).getLedger_hash());
startActivity(intent);
//Toast.makeText(this,"Hey there, you onClicked!", Toast.LENGTH_SHORT).show();
}
public List<LedgerResult> addToadapterLedgerResultList (LedgerResult ledgerResult1){
if(adapterLedgerResultList.size() != 0) {
adapterLedgerResultList.add(ledgerResult1);
/* myWebSocketAdapter.notifyItemInserted(adapterLedgerResultList.indexOf(ledgerResult1));
webSocketRecyclerView.scrollToPosition(adapterLedgerResultList.indexOf(ledgerResult1));*/
myWebSocketAdapter.notifyItemInserted(adapterLedgerResultList.size() - 1);
//myWebSocketAdapter.notifyDataSetChanged();
webSocketRecyclerView.scrollToPosition(adapterLedgerResultList.size() - 1);
return adapterLedgerResultList;
}
else {
adapterLedgerResultList.add(ledgerResult1);
myWebSocketAdapter.notifyItemInserted(0);
//myWebSocketAdapter.notifyDataSetChanged();
return adapterLedgerResultList;
}
}
public class MySimpleClient extends WebSocketClient {
public MySimpleClient( URI serverUri , Draft draft ) {
super( serverUri, draft );
}
public MySimpleClient( URI serverURI ) {
super( serverURI );
}
public MySimpleClient( URI serverUri, Map<String, String> httpHeaders ) {
super(serverUri, httpHeaders);
}
@Override
public void onOpen( ServerHandshake handshakedata ) {
send("{\n" +
" \"id\": 1,\n" +
" \"command\": \"subscribe\",\n" +
" \"accounts\": [],\n" +
" \"streams\": [\n" +
" \"server\",\n" +
" \"ledger\"\n" +
" ]\n" +
"}");
Log.d("SearchCode", "Connection opened!");
// if you plan to refuse connection based on ip or httpfields overload: onWebsocketHandshakeReceivedAsClient
}
@Override
public void onMessage(String message) {
try {
JSONObject obj = new JSONObject(message);
Gson gson = new Gson();
LedgerResult ledgerResult = gson.fromJson(obj.toString(),LedgerResult.class);
StreamExceptionHandler lilHandler = gson.fromJson(obj.toString(),StreamExceptionHandler.class);
if(lilHandler.getBase_fee() != null){
//do nothing.
}else {
adapterLedgerResultList = addToadapterLedgerResultList(ledgerResult);
if(adapterLedgerResultList.get(0).getLedger_index() == null){
LedgerResult tmp = adapterLedgerResultList.get(0);
adapterLedgerResultList.remove(tmp);
myWebSocketAdapter.notifyItemRemoved(0);
// myWebSocketAdapter.notifyDataSetChanged();
}
else {
bindIt();
Log.d("This is obj", obj.toString());
Log.d("LedgerResult", ledgerResult.toString());
}
}
} catch (Throwable t) {
Log.e("SeachCode", "Could not parse malformed JSON: \"" + message + "\"");
}
}
@Override
public void onClose( int code, String reason, boolean remote ) {
Log.e("SearchCode: ","Connection closed by " + ( remote ? "remote peer" : "us" ) + " Code: " + code + " Reason: " + reason);
}
@Override
public void onError( Exception ex ) {
ex.printStackTrace();
}
}
}
我的适配器代码 MyWebSocketAdapter 在这里:
package com.example.menes.searchcode.Websocketing;
import android.content.Context;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.menes.searchcode.R;
import java.util.List;
public class MyWebSocketAdapter extends RecyclerView.Adapter<MyWebSocketAdapter.WebSocketView> {
public interface OnItemClickListener {
void onItemClick (int position);
}
private MyWebSocketAdapter.OnItemClickListener onItemClickListener;
private Context context;
private List<LedgerResult> adapterLedgerResultList;
public MyWebSocketAdapter(Context context, List<LedgerResult> adapterLedgerResultList){
this.context = context;
this.adapterLedgerResultList = adapterLedgerResultList;
}
/*public MyWebSocketAdapter(Context context){
this.context = context;
}*/
/*public List<LedgerResult> addToadapterLedgerResultList (LedgerResult ledgerResult1){
adapterLedgerResultList.add(ledgerResult1);
if(adapterLedgerResultList.size() != 0) {
notifyItemInserted(adapterLedgerResultList.indexOf(ledgerResult1));
return adapterLedgerResultList;
}
else {
notifyItemInserted(0);
return adapterLedgerResultList;
}
}*/
public void setOnItemClickListener(MyWebSocketAdapter.OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
class WebSocketView extends RecyclerView.ViewHolder {
TextView otherThing;
TextView hashCode, textView;
public WebSocketView(View itemView) {
super(itemView);
hashCode = itemView.findViewById(R.id.hashCode);
otherThing = itemView.findViewById(R.id.otherThing);
textView = itemView.findViewById(R.id.textView);
}
}
@Override
public WebSocketView onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.in_recycler, parent, false);
return new WebSocketView(layoutView);
}
@Override
public void onBindViewHolder(WebSocketView holder, final int position) {
final WebSocketView hldr = holder;
LedgerResult row = adapterLedgerResultList.get(hldr.getAdapterPosition());
if(row.getLedger_hash() == null) {
holder.hashCode.setText("IT IS NULL");
}
else {
holder.hashCode.setText(row.getLedger_hash());
holder.hashCode.setTextColor(Color.parseColor("#239DEA"));
}
if(row.getLedger_index() == null) {
holder.otherThing.setText("IT IS NULL");
}
else {
holder.otherThing.setText(row.getLedger_index().toString());
}
if(row.getLedger_index() != null) {
String s = row.getValidated_ledgers().toString();
holder.textView.setText(s);
//holder.textView.setVisibility(View.VISIBLE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(onItemClickListener != null) {
onItemClickListener.onItemClick(hldr.getAdapterPosition());
}
}
});
}
/* @Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}*/
@Override
public int getItemCount() {
return adapterLedgerResultList.size();
}
}
我也检查了数百万次甚至重新创建的 XML 文件。
websocket_and_button_thing.xml 是:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/startButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Start"
app:layout_constraintBottom_toTopOf="@+id/stopButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/myRecyclerView"
app:layout_constraintVertical_bias="1.0" />
<Button
android:id="@+id/stopButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="Stop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
<android.support.v7.widget.RecyclerView
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:id="@+id/myRecyclerView"
android:layout_width="368dp"
android:layout_height="363dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
最后,inside-of-recyclerView 代码被称为 in-recycler.xml,它是:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="94dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:gravity="center_horizontal"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/hashCode" />
<TextView
android:id="@+id/hashCode"
android:layout_width="261dp"
android:layout_height="20dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/otherThing"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="@+id/otherThing"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</android.support.constraint.ConstraintLayout>
任何人都能够想出一个解决方案,为什么 TextViews 没有出现?
从 LOG 记录中我可以得到所有数据通过调试,我的列表也正常工作。
注意:我使用 StreamExceptionHandler 类来区分两个流结果。一个对我有用,另一个没用,这就是为什么如果我抓到什么我什么都不做。
另外,我的自定义类工作正常,因为我的列表似乎工作良好。
编辑后:
我改变了 WebSocketActivity 和适配器。没有太大变化。但现在,再次奇怪的是,我正在获取所有数据。它也被添加到 RecyclerView 中,但在我尝试手动滚动之前它不会显示出来。另外,每当有新数据到达时,RecyclerView 就会完全消失,然后如果我再次滚动,它会返回更新的数据。 更新后有什么解决方案?
【问题讨论】:
-
您是否检查过适配器的 onBindViewHolder() 方法中的数据也分配给了 textviews ?
-
所以您的
RecyclerView项目正在显示,但它们是空白的,因为TextView没有显示。您确定row.getLedger_hash()和row.getLedger_hash()返回非零长度字符串吗?很简单,但它确实发生了:我还要确保背景和文本颜色不一样。 -
奇怪的是,当我对那些 textview 分配设置断点时,它有时会到达那里,有时却不会。不知道为什么。但是,当它发生时,我看到 TextView 的分配工作正常。仍然没有显示出来。
-
对于非零长度字符串,我可以说是,因为我检查了列表的形成方式以及它们的组件是否正确。 getAdapterPosition 方法也可以正确使用它们。对一般结构有何评论?我更担心我在哪里初始化适配器以及在哪里设置它。我也尝试了不同的 layoutManager 初始化和赋值类型,但结果是一样的。
-
我编辑后你们能想出点什么吗? @Umair
标签: android websocket android-recyclerview java-websocket