SwipeRefreshLayout with EmptyView nullPointerException

孤者浪人 提交于 2019-12-10 20:26:45

问题


Whenever I swipe down to refresh, I get a NullPointerException but it's not in my code, rather in the startRefresh() method from SwipeRefreshLayout.

07-14 11:55:06.714: E/AndroidRuntime(20484): java.lang.NullPointerException
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.support.v4.widget.SwipeRefreshLayout.startRefresh(SwipeRefreshLayout.java:441)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.support.v4.widget.SwipeRefreshLayout.onTouchEvent(SwipeRefreshLayout.java:399)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.View.dispatchTouchEvent(View.java:7253)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2215)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1458)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.app.Activity.dispatchTouchEvent(Activity.java:2410)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2163)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.View.dispatchPointerEvent(View.java:7433)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:171)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4342)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4382)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.Choreographer.doCallbacks(Choreographer.java:562)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.Choreographer.doFrame(Choreographer.java:530)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.os.Handler.handleCallback(Handler.java:725)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.os.Handler.dispatchMessage(Handler.java:92)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.os.Looper.loop(Looper.java:137)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at android.app.ActivityThread.main(ActivityThread.java:5227)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at java.lang.reflect.Method.invokeNative(Native Method)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at java.lang.reflect.Method.invoke(Method.java:511)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
07-14 11:55:06.714: E/AndroidRuntime(20484):    at dalvik.system.NativeStart.main(Native Method)

`

This is my onCreate and onRefresh of my main Activity, MonitoredCoursesActivity:

public class MonitoredCoursesActivity extends ListActivity implements OnRefreshListener {

private SwipeRefreshLayout swipeLayout;
private ArrayList<Course> monitored;
private String lastUpdate;
private ListView myList;
private MyListAdapter myListAdapter;
final Context context = this;
//  private int freqUpdate;
//  private String updateTime;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (loadState()==null) {
        monitored = new ArrayList<Course>();
    }
    myList=(ListView)findViewById(android.R.id.list);
    myListAdapter = new MyListAdapter(context, R.layout.row, monitored);
    View empty = findViewById(android.R.id.empty);
    myList.setEmptyView(empty);
    myList.setAdapter(myListAdapter);
    myList.setLongClickable(true);
    registerForContextMenu(myList);

    swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
    swipeLayout.setOnRefreshListener(this);
    swipeLayout.setColorScheme(android.R.color.holo_blue_bright, 
            android.R.color.holo_green_light, 
            android.R.color.holo_orange_light, 
            android.R.color.holo_red_light);
    swipeLayout.setHapticFeedbackEnabled(true);
@Override
public void onRefresh() {
    new Handler().postDelayed(new Runnable() {
        @Override public void run() {
            //Refresh all courses in the list
            updateCoursesInfo();
            swipeLayout.setRefreshing(false);
        }
    }, 10000);
}

My activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:text="@string/courses" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="2"
        android:cacheColorHint="#000000"
        android:divider="#D5DDDE"
        android:dividerHeight="1dp"
        android:drawSelectorOnTop="false"
        android:focusableInTouchMode="false"
        android:footerDividersEnabled="false"
        android:headerDividersEnabled="true"
        android:listSelector="@android:color/transparent" />
</android.support.v4.widget.SwipeRefreshLayout>

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipeRefreshLayout_emptyView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbarStyle="outsideOverlay" >

        <TextView
            android:id="@android:id/empty"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical|center_horizontal"
            android:alpha="0.18"
            android:clickable="false"
            android:gravity="center|center_vertical|center_horizontal"
            android:longClickable="false"
            android:text="@string/empty_list"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@android:color/widget_edittext_dark"
            android:textSize="35sp"
            android:textStyle="bold"
            android:typeface="normal" />
    </ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

My row.xml for ListView items:

`

     <GridLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:columnCount="2" >

         <TextView
             android:id="@+id/txtCourseName"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="left"
             android:layout_marginBottom="2dp"
             android:paddingRight="5dp"
             android:text="@string/section"
             android:textSize="25sp" />

         <TextView
             android:id="@+id/txtSection"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_column="1"
             android:layout_gravity="center"
             android:layout_row="0"
             android:text="@string/section"
             android:textAppearance="?android:attr/textAppearanceMedium" />
     </GridLayout>

     <TextView
         android:id="@+id/txtRemaining"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginRight="68dp"
         android:text="@string/remaining"
         android:textAppearance="?android:attr/textAppearanceMedium" />

     <TextView
         android:id="@+id/txtCRN"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@string/crn"
         android:textAppearance="?android:attr/textAppearanceMedium" />

     <TextView
         android:id="@+id/txtFecha"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_horizontal|top"
         android:textAppearance="?android:attr/textAppearanceSmall" />
 </LinearLayout>`

I've searched and this is the only similar question, but the solution doesn't apply to my case (or at least I think so). Any clues? Thanks in advance.


回答1:


You need to have

context = this;

in onCreate

In

myListAdapter = new MyListAdapter(context, R.layout.row, monitored);// here you are using context

Context is available once activity is created

Line 441 is

mListener.onRefresh(); 

Looking at the source

public void setOnRefreshListener(OnRefreshListener listener) {
    mListener = listener;
}

So have you implemented OnRefreshListener properly in your Activity?

As discussed in the chat

Remove the second SwipeRefreshLayout

To set a empty view to listview read the below instead of having the other swiperefreshlayout

http://cyrilmottier.com/2011/06/20/listview-tips-tricks-1-handle-emptiness/




回答2:


So, after a long talk with user Raghunandan here, he pointed out that my xml had two different SwipeRefreshLayouts. This workaround was used in order to properly set an EmptyView on the ListView (as shown on the onCreate() method), but was all rubbish. The EmptyView worked, but one of those SwipeRefreshLayouts had a null onRefreshListener (the one for the EmptyView, of course). THIS caused the NullPointerException, naturally. Every piece of code remains the same. The only thing I had to change was the activity_main.xml:

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:text="@string/courses" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="2"
        android:cacheColorHint="#000000"
        android:divider="#D5DDDE"
        android:dividerHeight="1dp"
        android:drawSelectorOnTop="false"
        android:focusableInTouchMode="false"
        android:footerDividersEnabled="false"
        android:headerDividersEnabled="true"
        android:listSelector="@android:color/transparent" />
</android.support.v4.widget.SwipeRefreshLayout>

<TextView
    android:id="@android:id/empty"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical|center_horizontal"
    android:alpha="0.18"
    android:clickable="false"
    android:gravity="center|center_vertical"
    android:longClickable="false"
    android:text="@string/empty_list"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="@android:color/widget_edittext_dark"
    android:textSize="35sp"
    android:textStyle="bold"
    android:typeface="normal" />

Note: If you're having issues with ContextMenus not appearing, even after being correctly declared, this should fix it.

Be careful with your layouts!



来源:https://stackoverflow.com/questions/24742031/swiperefreshlayout-with-emptyview-nullpointerexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!