【问题标题】:Deleting a View in a class method在类方法中删除视图
【发布时间】:2021-11-05 13:10:34
【问题描述】:

在我的活动中,我尝试从一个类中调用一个方法,但它没有得到正确的值。 这是活动二:

int id = intent.getIntExtra("id", 0);
LayoutInflater inflater = getLayoutInflater();
View mainActivity = inflater.inflate(R.layout.activity_main, null);

LinearLayout eventsLayout = mainActivity.findViewById(R.id.eventsLayout);
Log.d("ACTIVITY_eventlayout", String.valueOf(eventsLayout)); // gives the layout perfectly
Event.RemoveSpecific(eventsLayout, id);

finish();

这是带有方法的类(事件):

public static void RemoveSpecific(LinearLayout layout, int id){
        View event = layout.findViewById(id);
        Log.d("INSIDE_removespecific", String.valueOf(event));// event is null
        layout.removeView(event);
}

在我的 MainActivity 中它工作正常:

LinearLayout eventsLayout = findViewById(R.id.eventsLayout);
View event = eventsLayout.findViewById(id);
//Log.d("MAIN_event", String.valueOf(event1)); // gives it perfectly
eventsLayout.removeView(event);

我还在我的 MainActivity 中添加了这个视图,并使用 .setId(id) 为其提供正确的 ID。所以我的问题是,为什么我的类方法中的 View 为 null,而我从我的 activityTwo 传递了正确的 LinearLayout?

id 是从哪里来的?

我有一个包含 id、名称、日期和描述的 Event 类。此类还有一个名为 eventsList 的静态 ArrayList。每当用户创建一个新提醒时,我使用我的类创建一个新事件并给它一个 ID 为Event.eventsList().size()(将其添加到我的 eventsList [所以第一个事件 id 始终为 1]),然后我创建一个新视图和传递最近创建的事件详细信息并使用setId() 为其指定一个 id [1]。然后在这个视图中,我有一个按钮,它有一个 onClickListener,它将给定的视图 ID 和 LinearLayout(添加视图的位置)传递给我的 Event.removeSpecific() 方法。

应用流程:

用户单击 MainActivity 中的按钮以创建事件,然后单击按钮然后使用 startActivityForResult() 意图打开一个新 Activity,用户在其中输入事件的名称、描述和日期,然后我创建使用putExtra() 方法的意图,然后使用setResult(RESULT_OK, resultintent) 将数据发送回MainActivity。现在,当 MainActivity 取回数据时,我使用 .getStringExtra() 使用数据创建一个新的 Event 对象并将其添加到 may Event.eventsList ArrayList,然后我使用以下内容:

LayoutInflater inflater = getLayoutInflater();
View event_Exmaple = inflater.inflate(R.layout.event_example, null);

并用我得到的数据设置 textView,并使用 event_example.setId(Event.eventsList.size()) 给它一个 id。 之后,我将它添加到我的 LinearLayout(我已经在 MainActivity 中声明):

eventsLayout.addView(event_example)

现在我提到了 Event 类有一个日期字段。我用它来使用 AlarmManager 设置警报。使用 AlarmManager,我通过意图发送当前 Event 对象的数据,当用户收到通知时,它会打开一个新的 Activity,该 Activity 会获取给定的 Event 对象数据(使用intent.putExtra()'s),这就是用户点击的部分一个按钮。我想从 MainActivity XML 中的 LinearLayout 中删除给定的 Event 对象的 View。

【问题讨论】:

    标签: java android android-studio android-linearlayout cardview


    【解决方案1】:

    好吧,因为您没有分享 id 值的来源(意图从哪里获取数据/您如何将值放入其中/值来自哪里),我假设这是解决方案:

    • 每当我使用带有 View Id 的“switch”语句时,它都会告诉我一个非常重要的警告,即

    在 Android Gradle 插件 5.0 版中,资源 ID 不是最终的,请避免在 switch case 语句中使用它们

    • 这意味着视图 Id 在某些情况下没有稳定的 id,您不应该认为它们是最终的。

    • 我猜在您的情况下,当您获得 事件视图 的 id 然后膨胀 布局视图 时,膨胀过程涉及更改 'int' id 值事件视图,因此每当您查询旧 id 时,它都会返回 null,因为膨胀的 布局视图 内的 事件视图 现在有一个新的“int” id 值。

    • 我不知道为什么它在主要活动中起作用,因为您没有共享从哪里获取 id 的完整代码。

    • 所以我想唯一的解决方案是你应该找到一种方法来获取新的 id 副本,然后在方法中扩展你想要处理的视图。

    更新

    问题在于这段代码
    View mainActivity = inflater.inflate(R.layout.activity_main, null);
    每次你膨胀一个新的布局视图时,认为你有一个被主要活动使用的布局视图,但是你正在创建一个具有新视图和新 ID 的全新布局视图。
    这就是为什么您可以在主要活动中获得视图但无法从新膨胀的视图中获得它的原因。

    更新

    如果您需要使用 id 删除此项并将静态数组存储在视图自定义类中,请在静态数组上调用 getter 并从中删除该项,而不是尝试删除视图本身。

    整个情况的一个更好的实现是使用房间而不是静态数组将这些事件存储在数据库中,这样你就可以通过一行代码随时删除/添加/编辑任何事件,如果你愿意的话要做到这一点,您可以先阅读房间的开发人员documentation

    【讨论】:

    • 我编辑了我的问题,希望它能澄清我的想法,也许我应该重写整个事情,因为我也看到它不是很简单?
    • 不,你确实不能,如果你确实有一些项目存储在自定义视图中的静态数组中,你为什么不调用自定义类的getter来获取这个数组并删除您要从数组本身中删除的项目。 (由于 item_id == item_pos +1,如果您要从数组中删除项目,请务必删除位置为 id-1 而不是 id 的项目)
    • 对整个情况的更好实现是使用房间而不是静态数组将此事件存储在数据库中,这样您就可以随时删除/添加/编辑任何事件,只需一行代码,如果您愿意这样做,您可以通过此链接阅读 room 的开发人员文档开始developer.android.com/training/data-storage/room
    • 我想用数据库来制作整个项目,但我想在本地测试它是如何工作的,我想对于这些类型的项目来说,使用数据库通常更容易,谢谢你answears 它真的帮了我很多!
    • 没问题,也感谢您的更新,它帮助我更好地理解了问题。
    猜你喜欢
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多