TextView в RecyclerView не отображается
Я давно пытаюсь исправить свой код. Я искал так много мест, чтобы найти решение, но безрезультатно. Если вы посмотрите на мой код и покажете, почему мои TextViews в RecylerView не отображаются, это было бы здорово.
Я пытаюсь использовать WebSocket-In и получать данные из Интернета. Это должно отображаться в RecyclerView в постоянно обновляемом виде. Регистры данных с пульсирующих серверов идут с естественной задержкой. Я хочу показать их некоторые аспекты в RecyclerView. Все TextViews могут меняться по содержанию, они просто пробуют это.
Вот мой код 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-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 не отображаются?
Из записей журнала я могу получить все данные. После отладки мои списки также работают правильно.
Примечание. Я использовал класс StreamExceptionHandler, чтобы различать результаты двух потоков. Один полезен для меня, другой нет, и поэтому я ничего не делаю, если что-то ловлю.
Кроме того, мои пользовательские классы работают правильно, так как мои списки, кажется, работают хорошо.
ПОСЛЕ РЕДАКТИРОВАНИЯ:
Я изменил WebSocketActivity и адаптер как таковой. Не так много изменилось. Но теперь, снова странно, я получаю все данные. Он также добавлен в RecyclerView, но не отображается, пока я не попытаюсь прокрутить вручную. Кроме того, всякий раз, когда поступают новые данные, RecyclerView полностью исчезает, затем, если я прокручиваю снова, он возвращается с обновленными данными. ЛЮБОЕ РЕШЕНИЕ после обновления?
2 ответа
Я думаю, я нашел это. Так как я изменил системный код и сам код, я не могу опубликовать точный код для его решения, но ключ переопределяет runOnUiThread
функция в пределах нажатия кнопки. И вы должны изменить RecyclerView
связывание и менеджерские наборы также. Сделай это в другом месте.
Переопределить runOnUiThread
в анонимном (внутреннем) классе используйте это:
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
Надеюсь, это поможет будущим посетителям.
Вы видите эту строку в MyWebSocketAdapter:
holder.textView.setVisibility(View.INVISIBLE);