【问题标题】:Android: how do I setEnabled(true) on a CardView in onResume?Android:如何在 onResume 中的 CardView 上设置启用(true)?
【发布时间】:2016-11-02 13:59:08
【问题描述】:

我有一个带有 CardViews 的 RecyclerView 列表。我在下面添加了以下代码来启动允许用户编辑 CardView 的活动 (ActActivity)。如果用户在 CardView 上快速连续单击多次,setEnabled(false) 代码用于阻止活动的多个实例打开。我只希望一次打开一个活动实例,以便用户只编辑他们单击的单个 CardView。

我的问题是,当我添加 onResume() 部分以将 setEnabled() 重新设置为“true”时,应用程序崩溃了。当我删除 onResume() 部分时,setEnabled(false) 代码通过不允许打开活动的多个实例而正常工作,但问题是 CardView 上的任何双击都会禁用未来的单击以正确启动 ActActivity。

我在这里错过了什么?

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);
}

RecyclerView 的 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: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>

CardView 的 xml 文件:

<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 输出不喜欢 onResume() 部分中的“cardView1.setEnabled(true)”行:

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) 

一个可行的建议答案是:

...     
@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);
        }
    });
 }

这与使用 onResume 的答案相比如何?

【问题讨论】:

  • 如果应用崩溃,请发布您的 logcat 信息
  • 我们可以得到你的错误日志吗?
  • 好的,现在添加。
  • 添加了 logcat 信息。
  • 看起来CardView 在调用findViewById 后为空。 Activity 布局是什么样的?

标签: android android-recyclerview android-cardview


【解决方案1】:

这里有问题.....

CardViewrecycle view 中,您正在尝试使用main layout 而不是item layout ....

这是您的问题的解决方案....

创建cardview 变量为global .......

private CardView cardview;

item clicked 时使用它......

@Override
public void onItemClick(int position, View view) {
    cardview = (CardView) view;
    cardview.setEnabled(false);
    ActActivity.start(this, contactListAdapter.getItem(position));
}

注意:- 始终尝试声明在许多方法中使用的全局变量 .....

编辑:-在您的onResume....中尝试第一次运行。

并设置条件 onResume ....

 Override
    protected void onResume() {
        super.onResume();
        if(cardview!=null){
        cardview.setEnabled(true);

     }

上述问题将解决您的首次运行问题....

【讨论】:

  • 我会试试的。另一个建议: 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); } });这很好用。您对此解决方案与使用 onResume 代码的解决方案有何看法?
  • 它会在第一次运行时崩溃,因为第一次调用onResumecardview 将是null
  • @sushildh 应用程序崩溃。
  • 看看编辑答案...它解决了你的问题。您不需要任何线程......
  • @sushildlh 删除第一次运行检查并添加null 检查,因为如果活动第二次转到onResume 并且未调用onItemClick,它仍然会崩溃。
【解决方案2】:

您可以在活动的 onCreate 中初始化卡片视图,而不是在 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);
    }

【讨论】:

  • 好的,我试试看。
  • 同样的结果。应用程序崩溃并且 logcat 说是由以下行引起的:“cardView1.setEnabled(true);”
  • 您必须在访问 cardView 之前检查 null 条件。因为 onResume 一开始会被调用。
【解决方案3】:

在下面的代码之前你有没有初始化 RecyclerView 联系人列表:

CardView cardView1 = (CardView)findViewById(R.id.singlecard_view1);

如果您还没有创建卡片视图,则不会创建 findViewById(R.id.singlecard_view1); 将返回 null。

已编辑:
我认为 RecyclerView 的项目的视图在活动完全可见之前没有被初始化,这导致 findViewById(R.id.singlecard_view1) 返回 null。

但正如您所说,您只希望编辑活动只启动一次。 您可以通过
-> 在清单文件中为“ActActivity”添加android:launchMode="singleTask" 来实现此目的。

-> 将 FLAG_ACTIVITY_CLEAR_TASK 添加到 Intent。

【讨论】:

  • 是的,列表已创建,然后用户单击其中一个 CardView 进行编辑。我试图阻止打开同一 CardView 的多个实例。
  • 你在哪里初始化列表?我的意思是设置它的布局管理器和适配器。
  • 参见上面的编辑,它位于 MainActivity 文件的顶部。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 2016-08-03
  • 1970-01-01
  • 2019-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多