问题
I have a RecyclerView list with CardViews. I added the following code below to launch an activity (ActActivity) that allows the user to edit the CardView. The setEnabled(false)
code is used to keep multiple instances of the activity from opening if the user clicks multiple times in rapid succession on the CardView. I only want one instance of the activity to be open at one time so that the user is only editing the single CardView that they clicked on.
My problem is that when I add the onResume()
section to re-set setEnabled()
to "true" the app crashes. When I remove the onResume() section then the setEnabled(false) code works correctly by not allowing multiple instances of the activity to open, but the problem is that any doubleclicks on the CardView disable a future single-click to correctly launch the ActActivity.
What am I missing here?
MainActivity.java
public class MainActivity extends AppCompatActivity implements
RecyclerItemClickListener {
lvContact = (RecyclerView) findViewById(R.id.lvContact);
assert lvContact != null;
lvContact.setHasFixedSize(true);
contactListAdapter = new ContactListAdapter(this);
contactListAdapter.setOnItemClickListener(this);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
lvContact.setLayoutManager(layoutManager);
lvContact.setAdapter(contactListAdapter);
...
@Override
public void onItemClick(int position, View view) {
CardView c = (CardView) view;
c.setEnabled(false);
ActActivity.start(this, contactListAdapter.getItem(position));
}
...
Override
protected void onResume() {
super.onResume();
CardView cardView1 = (CardView) findViewById(R.id.singlecard_view1);
cardView1.setEnabled(true);
}
xml file for the RecyclerView:
<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:background="#FFFFFF"
tools:context="com.v050.MainActivity">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" >
</include>
<LinearLayout
android:id="@+id/todoListLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar"
android:layout_above="@+id/s4"
android:background="@color/background4main"
android:layout_marginTop="6dp"
android:layout_marginStart="6dp"
android:layout_marginLeft="6dp"
android:layout_marginEnd="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="6dp"
android:orientation="vertical" >
<android.support.v7.widget.RecyclerView
android:id="@+id/lvContact"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</LinearLayout>
<TextView
android:id="@+id/s4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:background="@color/colorPrimary"
android:textAppearance="?android:attr/textAppearanceMedium"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:clickable="true" />
</RelativeLayout>
xml file for the CardView:
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/singlecard_view1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
card_view:cardBackgroundColor="@android:color/white"
card_view:cardCornerRadius="6dp"
card_view:cardElevation="4dp"
android:foreground="?android:attr/selectableItemBackground"
android:longClickable="true" >
Logcat output does not like the "cardView1.setEnabled(true)" line in the onResume() section:
11-01 23:22:54.814 1399-1399/com.example.v50 E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to resume activity {com.example.v50/com.v050.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.v050.MainActivity.onResume(MainActivity.java:279)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)
at android.app.Activity.performResume(Activity.java:5082)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
One proposed answer that works is:
...
@Override
public void onItemClick(int position, final View view) {
view.setEnabled(false);
ActActivity.start(this, contactListAdapter.getItem(position));
view.post(new Runnable() {
@Override
public void run() {
view.setEnabled(true);
}
});
}
How does this compare to answers that use onResume?
回答1:
Here is problem .....
CardView
is in the recycle view
and you are trying from the main layout
instead of item layout
....
here is your solution for your problem....
create cardview
variable as global
.......
private CardView cardview;
use it when the item clicked
......
@Override
public void onItemClick(int position, View view) {
cardview = (CardView) view;
cardview.setEnabled(false);
ActActivity.start(this, contactListAdapter.getItem(position));
}
Note:- Always try to declare global variable which have use in many methods .....
EDIT:- try this for the first run in your onResume
....
and put condition onResume ....
Override
protected void onResume() {
super.onResume();
if(cardview!=null){
cardview.setEnabled(true);
}
above problem will solve your First Run problem ....
回答2:
You can initialise the card view in onCreate of activity instead of onResume.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CardView cardView1 = (CardView)findViewById(R.id.singlecard_view1);
}
Override
protected void onResume() {
super.onResume();
cardView1.setEnabled(true);
}
回答3:
Have you initialized the RecyclerView contact list before following code:
CardView cardView1 = (CardView)findViewById(R.id.singlecard_view1);
If you haven't then the card view will not be created and findViewById(R.id.singlecard_view1);
will return null.
Edited:
I think the view of the RecyclerView's items are not getting initialized untill activity is fully visible which cause findViewById(R.id.singlecard_view1)
return null.
But as you have said you just want the edit activity to be started only once.
You can achieve this by
-> adding android:launchMode="singleTask"
for "ActActivity" in manifest file.
OR
->adding FLAG_ACTIVITY_CLEAR_TASK to Intent.
来源:https://stackoverflow.com/questions/40372223/android-how-do-i-setenabledtrue-on-a-cardview-in-onresume