Android Studio CoordinatorLayout& RecyclerView空白? [英] android studio CoordinatorLayout & RecyclerView blank?
问题描述
运行我的应用程序时,我得到一个空的活动,暂时我只有一个列表,应该通过从JSON读取这些图像地址以及从logcat中读取这些图像的地址来投影图像,我可以看到这些地址已传递给该应用程序,并记录下来,但不确定为什么布局没有结构化,而我却得到了空白的空白屏幕.
Runing my app i get a blank activity, for the time being i only have a list which should be projecting images, by reading these images addresses from JSON, and from the logcat i could see the the addresses being passed to the app, and logged, but not sure why the layout is not getting structured and i get a blank white screen.
使用Genymotion-android s6-android studio 2.1.1
Using Genymotion - android s6 - android studio 2.1.1
MyActivity;
MyActivity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
ArrayList<String> image_urls = new ArrayList<String>();
String[] android_image_urls = new String[image_urls.size()];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Firebase.setAndroidContext(this);
ImagesAddresses();
initViews();
}
public void ImagesAddresses(){
Firebase ref = new Firebase("https://xxxxx.firebaseio.com/xxxxxx/xxx");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
Map<String, String> allADR = (HashMap<String, String>) snapshot.getValue();
if (allADR != null) {
Collection<String> BlkADR = allADR.values();
image_urls.addAll(BlkADR);
android_image_urls = image_urls.toArray(android_image_urls);
Log.i("myTag", image_urls.toString());
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
private void initViews(){
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
ArrayList androidVersion = prepareData();
DataAdapter adapter = new DataAdapter(getApplicationContext(),androidVersion);
recyclerView.setAdapter(adapter);
}
private ArrayList prepareData(){
ArrayList android_version = new ArrayList<>();
for(int i=0;i<android_image_urls.length;i++){
AndroidVersion androidVersion = new AndroidVersion();
androidVersion.setAndroid_image_url(android_image_urls[i]);
android_version.add(androidVersion);
}
return android_version;
}
}
activity_main.xml;
activity_main.xml;
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.v7.widget.RecyclerView
android:id="@+id/card_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.design.widget.CoordinatorLayout>
DataAdapter.java;
DataAdapter.java;
package net.janusjanus.interactive_layout;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<AndroidVersion> android_version;
private Context context;
public DataAdapter(Context context,ArrayList<AndroidVersion> android_version) {
this.context = context;
this.android_version = android_version;
}
@Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_layout, viewGroup, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
Picasso.with(context).load(android_version.get(i).getAndroid_image_url()).resize(120, 60).into(viewHolder.img_android);
}
@Override
public int getItemCount() {
return android_version.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView img_android;
public ViewHolder(View view) {
super(view);
img_android = (ImageView)view.findViewById(R.id.img_android);
}
}
}
AndroidVersion.java;
AndroidVersion.java;
package net.janusjanus.interactive_layout;
public class AndroidVersion {
private String android_image_url;
public String getAndroid_image_url() {
return android_image_url;
}
public void setAndroid_image_url(String android_image_url) {
this.android_image_url = android_image_url;
}
}
解决错误,我得到了跟进;
going over the error i got the followin;
05-15 04:19:57.942 7827-7875/net.janusjanus.interactive_layout I/OpenGLRenderer: Initialized EGL, version 1.4
05-15 04:19:58.055 7827-7875/net.janusjanus.interactive_layout W/EGL_emulation: eglSurfaceAttrib not implemented
05-15 04:19:58.056 7827-7875/net.janusjanus.interactive_layout W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe7d65fe0, error=EGL_SUCCESS
05-15 04:20:01.188 7827-7827/net.janusjanus.interactive_layout I/myTag: [http://res.cloudinary.com/xxxxx/image/xxxxxx/xxxxxx/fw88v6xu6wybamg9zzt6.jpg, http://res.cloudinary.com/xxxx/image/upload/xxxxx/xxxxdgfddd.jpg, http://res.cloudinary.com/xxxxxxx/jjjjjj/upload/xxxxxxxx/vvvghgggggg.jpg]
DataAdapter.java; 而且我已经在stackoverflow上搜索了未实现的eglSurfaceAttrib
DataAdapter.java; and i have searched stackoverflow for eglSurfaceAttrib not implemented
增加了仿真器磁盘的大小,实现了Gapp以及我在以下文章中发现的其他说明; Android Studio-仿真器-eglSurfaceAttrib未实现
increased the emulator disk size, implemented Gapp and other instructions i found on the following posts; Android Studio - Emulator - eglSurfaceAttrib not implemented
但仍然没有布局.
正如下面的用户所建议的,我将initView的初始化更改为ImageAddresses的末尾,以使其遵循检索地址的步骤,并记录了android_version.size();.会返回零,因此布局仍为空白,但不确定如何解决此问题,
As the user below suggested, i changed the initialization of initView, into the end of ImageAddresses, in order for it to follow the step of retrieving the addresses, and also logged the android_version.size(); which returns zero, thus the layout is still blank but not sure how to fix this problem,
更改后的Logcat;
Logcat after changes ;
05-15 05:59:25.025 3473-3537/net.janusjanus.interactive_layout I/OpenGLRenderer: Initialized EGL, version 1.4
05-15 05:59:25.174 3473-3537/net.janusjanus.interactive_layout W/EGL_emulation: eglSurfaceAttrib not implemented
05-15 05:59:25.174 3473-3537/net.janusjanus.interactive_layout W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe08c47a0, error=EGL_SUCCESS
05-15 05:59:25.253 3473-3473/net.janusjanus.interactive_layout I/myTag: 0
05-15 05:59:25.253 3473-3473/net.janusjanus.interactive_layout I/myTag: 0
05-15 05:59:25.655 3473-3473/net.janusjanus.interactive_layout I/myTag: 0
05-15 05:59:25.656 3473-3473/net.janusjanus.interactive_layout I/myTag: 0
05-15 05:59:25.656 3473-3473/net.janusjanus.interactive_layout I/myTag: 0
显然,此错误的原因是执行方法的时间冲突,因此,正如您所建议的那样,我正在尝试使用runOnUiThread,我不确定如何在我的代码中正确构建,到目前为止,我已经尝试过我的MainActivity中的以下内容;
Apparently the cause of this error is a conflict in timing in executing methods, thus as suggested by of you i am trying to user runOnUiThread, which i am not sure how to construct properly within my code, so far i've tried the following in my MainActivity;
public class MainActivity extends AppCompatActivity {
ArrayList<String> image_urls = new ArrayList<String>();
String[] android_image_urls = new String[image_urls.size()];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Firebase.setAndroidContext(this);
ImagesAddresses();
}
public void ImagesAddresses(){
Firebase ref = new Firebase("https://xxxxx.firebaseio.com/xxxxx/xxxxx");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
Map<String, String> allADR = (HashMap<String, String>) snapshot.getValue();
if (allADR != null) {
Collection<String> BlkADR = allADR.values();
image_urls.addAll(BlkADR);
android_image_urls = image_urls.toArray(android_image_urls);
//私有最终字符串android_image_urls [] = android_image_urls
// private final String android_image_urls[]=android_image_urls
Log.i("myTag", image_urls.toString());
initViews();
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
private void initViews(){
runOnUiThread(new Runnable() {
public void run() {
//Do something on UiThread
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
ArrayList androidVersion = prepareData();
DataAdapter adapter = new DataAdapter(getApplicationContext(),androidVersion);
recyclerView.setAdapter(adapter);
}
});
}
private ArrayList prepareData(){
ArrayList android_version = new ArrayList<>();
for(int i=0;i<android_image_urls.length;i++){
AndroidVersion androidVersion = new AndroidVersion();
androidVersion.setAndroid_image_url(android_image_urls[i]);
android_version.add(androidVersion);
}
return android_version;
}
} 但我想这不是正确的方法,因为该应用程序仍会崩溃-并且出现以下错误;
} But i guess it is not the right way to do it, since the app still crash - and i get the following errors;
05-15 07:11:34.935 11327-11327/net.janusjanus.interactive_layout E/AndroidRuntime: FATAL EXCEPTION: main
Process: net.janusjanus.interactive_layout, PID: 11327
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.support.v7.widget.RecyclerView$LayoutManager.canScrollVertically()' on a null object reference
at android.support.v7.widget.RecyclerView.computeVerticalScrollRange(RecyclerView.java:1654)
at android.view.View.onDrawScrollBars(View.java:13924)
at android.view.View.onDrawForeground(View.java:17657)
at android.view.View.draw(View.java:16189)
at android.support.v7.widget.RecyclerView.draw(RecyclerView.java:3097)
at android.view.View.updateDisplayListIfDirty(View.java:15174)
at android.view.View.draw(View.java:15948)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.support.design.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1077)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.draw(View.java:16181)
at android.view.View.updateDisplayListIfDirty(View.java:15174)
at android.view.View.draw(View.java:15948)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.updateDisplayListIfDirty(View.java:15169)
at android.view.View.draw(View.java:15948)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.updateDisplayListIfDirty(View.java:15169)
at android.view.View.draw(View.java:15948)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.updateDisplayListIfDirty(View.java:15169)
at android.view.View.draw(View.java:15948)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.updateDisplayListIfDirty(View.java:15169)
at android.view.View.draw(View.java:15948)
at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at android.view.View.draw(View.java:16181)
at com.android.internal.policy.PhoneWindow$DecorView.draw(PhoneWindow.java:2690)
at android.view.View.updateDisplayListIfDirty(View.java:15174)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2615)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2434)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2067)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
推荐答案
在ImagesAddresses();
中,您使用Firebase
从Web服务中检索数据,然后通过委托方法获得结果.
onDataChange
.由于此方法的执行是异步的,因此发生的情况是在调用onDataChange
之前先调用initViews();
并因此调用prepareData()
.如您所见,图像android_image_urls
仍然为空.您需要做的就是从onDataChange
调用initViews();
,确保initViews();
在UI Thread
上运行.
In ImagesAddresses();
you are using Firebase
to retrieve the data from your webservice, and you get the results through the delegate method
onDataChange
. Since the execution of this method is asynchronous, what happens is that initViews();
and, therefore prepareData()
, are called before onDataChange
is called. As you can image android_image_urls
is still empty. What you have to do to fix is to call initViews();
from onDataChange
, making sure that it, initViews();
, runs on the UI Thread
.
这篇关于Android Studio CoordinatorLayout& RecyclerView空白?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!