ListView 中的可见性消失

Posted

技术标签:

【中文标题】ListView 中的可见性消失【英文标题】:Visibility GONE in ListView 【发布时间】:2015-02-17 18:12:24 【问题描述】:

我使用ListView 来显示TextViews。我的应用如下所示:

当我点击一个单词时它会消失:

ListView 仍然保留空行。我希望我的应用在点击后看起来像这样:

有谁知道为什么空行保持原位。为什么没有完全删除?我使用setVisibility(View.GONE) 使TextViews 消失。

当我简单地使用 TextviewsLinearLayouts 并将可见性设置为 GONE 时,整行会消失,下面的行会自动重新调整。

编辑:我将代码编辑为现在包含adapter.remove(adapter.getItem(position)),这会导致我的应用程序崩溃。我添加了错误日志并编辑了代码。请帮忙。

已编辑代码:

package com.example.listview;

public class MainActivity extends ActionBarActivity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        populateListView();
        registerClickCallback();
    

    private void populateListView() 

        //Create list of items
        String[] myItems = "Blue", "Green","Purple","Red";

        //Build Adapter
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.items, myItems);

        //Configure the list view
        ListView list = (ListView) findViewById(R.id.listView1);
        list.setAdapter(adapter);
    

    private void registerClickCallback() 
        ListView list = (ListView) findViewById(R.id.listView1);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() 

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) 

                TextView textview = (TextView) view;
                textview.setVisibility(View.GONE);
                adapter.remove(adapter.getItem(position));
            
    ); 



错误日志:

12-19 12:04:57.994: E/androidRuntime(23120): FATAL EXCEPTION: main
12-19 12:04:57.994: E/AndroidRuntime(23120): Process: com.example.listview, PID: 23120
12-19 12:04:57.994: E/AndroidRuntime(23120): java.lang.UnsupportedOperationException
12-19 12:04:57.994: E/AndroidRuntime(23120):    at java.util.AbstractList.remove(AbstractList.java:638)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at java.util.AbstractList$SimpleListIterator.remove(AbstractList.java:75)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at java.util.AbstractCollection.remove(AbstractCollection.java:229)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.widget.ArrayAdapter.remove(ArrayAdapter.java:244)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at com.example.listview.MainActivity$1.onItemClick(MainActivity.java:50)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2911)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.widget.AbsListView$3.run(AbsListView.java:3645)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.os.Handler.handleCallback(Handler.java:733)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.os.Handler.dispatchMessage(Handler.java:95)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.os.Looper.loop(Looper.java:136)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at android.app.ActivityThread.main(ActivityThread.java:5146)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at java.lang.reflect.Method.invokeNative(Native Method)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at java.lang.reflect.Method.invoke(Method.java:515)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
12-19 12:04:57.994: E/AndroidRuntime(23120):    at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

【参考方案1】:

你可以这样做

adapter.remove(adapter.getItem(position));

更新:正如 Gabe 所提到的,如果您需要根据其他事件显示/隐藏这些项目,您可能需要创建一个自定义适配器并跟踪状态,以便您可以在回收时正确设置行的可见性。还有许多库可能会有所帮助,例如 FunDapter、easy-adapter 等。

更新 2:remove() 仅在支持列表支持 .remove() 操作时才有效...所以你可以这样做 new ArrayAdapter&lt;String&gt;(this, R.layout.items, new ArrayList(Arrays.asList(myItems)));

【讨论】:

adapter.remove(adapter.getItem(position)) 使我的应用程序崩溃 我用错误日志和 adapter.remove 方法编辑了我的原始帖子。请看一下,如果您能提供帮助,请告诉我。感谢您迄今为止的帮助。 哦,有趣。这是因为您正在传递一个数组,其中包含 Arrays.asList().. ,它返回一个未实现 remove() 方法的 List 。你可以试试new ArrayAdapter&lt;String&gt;(this, R.layout.items, new ArrayList(Arrays.asList(myItems)));【参考方案2】:

我看到很多人建议您从数据集中删除字符串。我不建议这样做,特别是如果您想要一个项目可以通过其他事件更改其可见性的版本。执行此操作的常用方法是创建一个自定义适配器,该适配器跟踪每个索引处的字符串值和项目的可见性。然后在 getView 中,您必须正确设置给定索引的文本视图的可见性。

仅仅设置文本视图的可见性是不好的,因为列表视图使用视图回收。这会导致每个 textview 中显示的索引在运行时发生变化,因此直接更改 textview 的可见性而不在 getView 中正确设置会导致映射更改时出现问题。

【讨论】:

同意。如果将单独删除和添加行,则可以很好地实现适配器。如果这不是必需的,那么实现自定义适配器就太过分了,最好只使用可用的 API。您可以使用 adapter.clear() adapter.addAll(myItems) 重置适配器的全部内容【参考方案3】:

您正在更改文本视图的可见性,而不是其父视图 - 行项目。执行此操作的理想方法是从您的 list 中删除所选项目,然后在适配器上调用 notifyDatasetChanged()

【讨论】:

以上是关于ListView 中的可见性消失的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 中的不可见性、消失、可见性 ROW 和列

Android 中的可见性消失

当我将 ImageView 的可见性设置为线性布局消失时,它的一个孩子仍然存在,另一个在 android 中消失了

Coordinatorlayout 中的 VIewpager 在可见性消失时占用了额外的空间

ListView 使 textview 在超出屏幕可见性时可见

基于布尔值的 ListView 项目可见性