【问题标题】:setVisibility(View.GONE) not removing space in listview itemsetVisibility(View.GONE) 不删除列表视图项中的空间
【发布时间】:2014-08-01 08:38:13
【问题描述】:

我提出的问题可能类似于重复的问题,但我已经尝试了所有方法,但对我没有任何效果。我创建了一个 listview,每个项目都有两个视图,一个 textview 和一个 checkbox。它就像一个多选列表视图。每个项目都有自己的级别:简单、正常、困难。当从下拉列表中选择一个级别时:全部、简单、普通、困难.. 列表会发生变化,就像过滤系统一样。 但是当我写listView.getChildAt(i).setVisibility(View.GONE);时,该行的内容被删除但占用的空间没有被释放。

有什么帮助吗?

这是我的代码:

public class CreatePresentation extends Activity
{
    DatabaseHelper db = new DatabaseHelper(this);
    MyCustomAdapter dataAdapter = null;
    List<Slider> list;
    ListView listView;
    String Text;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.create_presentation);
        displayListView();
        checkButtonClick();
    }

    private void displayListView()
    {
        list = new ArrayList<Slider>();
        ArrayList<Slider> oldList = db.getAllSliders();

        for (Slider anOldList : oldList) {
            String s = anOldList.toString();
            int in = anOldList.getId();
            String lev = anOldList.getLevel();
            Slider slider = new Slider(in, s, lev, false);
            list.add(slider);
        }
        dataAdapter = new MyCustomAdapter(this, R.layout.list_check_box, list);
        listView = (ListView) findViewById(R.id.listView);
        listView.setAdapter(dataAdapter);
    }

    private class MyCustomAdapter extends ArrayAdapter<Slider> {
        private ArrayList<Slider> list;

        public MyCustomAdapter(Context context, int textViewResourceId, List<Slider> list) {
            super(context, textViewResourceId, list);
            this.list = new ArrayList<Slider>();
            this.list.addAll(list);
        }

        private class ViewHolder {
            TextView text;
            CheckBox checkbox;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            final ViewHolder holder;
            final Slider slider = list.get(position);

            if (convertView == null) {
                LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = vi.inflate(R.layout.list_check_box, null);

                holder = new ViewHolder();

                holder.text = (TextView) convertView.findViewById(R.id.sliderTitle);
                holder.checkbox = (CheckBox) convertView.findViewById(R.id.checkBox);
                convertView.setTag(holder);

                Spinner dropdown = (Spinner)findViewById(R.id.spinner);
                String[] items = new String[]{"Tutto", "Facile", "Medio", "Difficile"};
                ArrayAdapter<String> adapter = new ArrayAdapter<String (CreatePresentation.this, android.R.layout.simple_spinner_item, items);
                dropdown.setAdapter(adapter);

                Text = dropdown.getSelectedItem().toString();

                holder.checkbox.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        CheckBox cb = (CheckBox) v;
                        Slider slider = (Slider) cb.getTag();
                        slider.setSelected(cb.isChecked());
                    }
                });

                try {
                    if (list.get(position).getLevel().equals("Facile"))
                        convertView.setBackgroundColor(Color.parseColor("#477C3D"));
                    else if (list.get(position).getLevel().equals("Medio"))
                        convertView.setBackgroundColor(Color.parseColor("#936019"));
                    else if (list.get(position).getLevel().equals("Difficile"))
                        convertView.setBackgroundColor(Color.parseColor("#A02307"));
                } catch (Throwable e) {
                    e.printStackTrace();
                }

                dropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, final int position, long id) {
                        Text = parentView.getItemAtPosition(position).toString();
                        try {
                            if (Text.equals("All")){
                                Runnable run = new Runnable(){
                                    public void run(){
                                        for (int i = 0; i < list.size(); i++) {
                                            listView.getChildAt(i).setVisibility(View.VISIBLE);
                                        }
                                    }
                                };
                                runOnUiThread(run);
                            }
                            if (Text.equals("Easy")){
                                Runnable run = new Runnable(){
                                    public void run(){
                                        for (int i = 0; i < list.size(); i++) {
                                            if (list.get(i).getLevel().equals("Easy")) {
                                                listView.getChildAt(i).setVisibility(View.VISIBLE);
                                            }
                                            else {
                                                listView.getChildAt(i).setVisibility(View.GONE);
                                            }
                                        }
                                    }
                                };
                                runOnUiThread(run);
                            }
                            if (Text.equals("Normal")){
                                Runnable run = new Runnable(){
                                    public void run(){
                                        for (int i = 0; i < list.size(); i++) {
                                            if (list.get(i).getLevel().equals("Normal"))
                                                listView.getChildAt(i).setVisibility(View.VISIBLE);
                                            else {
                                                listView.getChildAt(i).setVisibility(View.GONE);
                                            }
                                            dataAdapter.notifyDataSetChanged();
                                        }
                                    }
                                };
                                runOnUiThread(run);
                            }
                            if (Text.equals("Hard")){
                                Runnable run = new Runnable(){
                                    public void run(){
                                        for (int i = 0; i < list.size(); i++) {
                                            if (list.get(i).getLevel().equals("Hard"))
                                                listView.getChildAt(i).setVisibility(View.VISIBLE);
                                            else
                                                listView.getChildAt(i).setVisibility(View.GONE);
                                        }
                                    }
                                };
                                runOnUiThread(run);
                            }
                        } catch (Throwable e) {
                            e.printStackTrace();
                        }
                    }
                    @Override
                    public void onNothingSelected(AdapterView<?> parentView) {
                    }
                });

                holder.checkbox.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        CheckBox cb = (CheckBox) v;
                        Slider slider = (Slider) cb.getTag();
                        slider.setSelected(cb.isChecked());
                    }
                });
            }
            else
            {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.text.setText(slider.getQuestion());
            holder.checkbox.setChecked(slider.isSelected());
            holder.checkbox.setTag(slider);

            return convertView;
        }
    }

【问题讨论】:

  • 你想从列表视图中删除完整的行吗?
  • 是的,即使有空格..
  • 所以你需要从列表中删除条目并执行 notifyadapter
  • 你不知道你会有多少过滤器吗?因为如果你这样做了,你可以创建一个带有vertical 方向的LinearLayout,然后只需添加带有includeadapter
  • 我认为在更改 ListView 中的任何内容后,您应该刷新它以便应用布局更改,这是一个关于它的问题帖子:stackoverflow.com/questions/4903758/…

标签: android listview


【解决方案1】:

最好的方法是从列表中删除项目并调用 dataAdapter.notifyDataSetChanged()

【讨论】:

    【解决方案2】:

    由于您想删除视图但将项目保留在列表中,我建议您使用不同的方法。当用户选择将导致项目隐藏的值时,只需将该值设置为您的项目,然后调用

      dataAdapter.notifyDataSetChanged();
    

    这样做您必须修改 getView() 中的逻辑,我的意思是,如果您在 customAdapter 的 getView() 方法中找到有资格隐藏而不是返回 convertView 的项目,则只需返回一个空视图,例如您的项目不会显示,但仍会在您的列表中;)

    【讨论】:

      【解决方案3】:

      您可以使用 Yuor 项目的父布局来解决问题:

      例如:

      <LinearLayout ...>
      
          <!-- Here Your item content starts -->
          <LinearLayout android:id="@+id/content">
      
          ...
      
          </LinearLayout>
          <!-- Here Your content ends -->
      
      </LinearLayout>
      

      Java 代码:

      listView.getChildAt(i).getChildAt(0).setVisibility(View.GONE);
      

      【讨论】:

        【解决方案4】:

        just like a filter system。为什么“喜欢”,为什么不让它真正可过滤?有两种选择。更简单的方法是覆盖滑块的toString。另一种是创建自定义过滤器,它不会使用对象的toString 方法。但是,我不记得具体怎么做第二个,只知道它是可能的。

        Slider:
            String toString(){
                return this.type;
            }
        When spinner selection changes:
            adapter.getFilter().filter(selectedDifficulty);
        

        这将自动显示您想查看的项目。

        【讨论】:

          【解决方案5】:

          您不应该更改适配器生成的视图的可见性 - 每次滚动列表视图时它们都会更改。相反,您应该更改底层适配器的行为。

          【讨论】:

            【解决方案6】:

            您可以尝试这种布局,而不是 ListView,因为只有 4 个过滤器:

            <LinearLayout 
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" >
            
               <include
                    android:id="@+id/filter_1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    layout="@layout/<your_listview_adapter>"
                    android:visibility="visible" />
            
               <include
                    android:id="@+id/filter_2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    layout="@layout/<your_listview_adapter>"
                    android:visibility="visible" />
            
               <include
                    android:id="@+id/filter_3"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    layout="@layout/<your_listview_adapter>"
                    android:visibility="visible" />
            
               <include
                    android:id="@+id/filter_4"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    layout="@layout/<your_listview_adapter>"
                    android:visibility="visible" />
            
            </LinearLayout>
            

            当您想隐藏其中一个过滤器时,您可以执行以下操作:

            findViewById(R.id.filter_4).setVisibility(View.GONE);
            

            编辑:

            例如,如果您想在first include 中向TextView 添加信息,您只需像这样调用View

            View filter1 = findViewById(R.id.filter_1); 
            TextView tv1 = (TextView) filter1.findViewById(R.id.<the_id_of_the_textview);
            tv1.setText("StackOverflow filter");
            

            【讨论】:

            • 我正在考虑您的建议@Akagami.. 我已经创建了 4 个其他布局 filter_1、filter_2 等等.. 但是我如何调用特定过滤器的数据?
            • 见编辑区的例子。
            【解决方案7】:

            为了防止在布局之外添加另一个布局。您只需隐藏项目的所有子视图,而不是项目本身。

            例如:

             if(i == 1){ // assume we need hide the first item. 
                //item itself
                ViewGroup parent = ((ViewGroup) holder.convertView);
                for (int j = 0; j < parent.getChildCount(); j++) {
                    parent.getChildAt(j).setVisibility(View.GONE);
                 }
             }
            

            我已经测试了这段代码,对我来说很好。

            【讨论】:

              猜你喜欢
              • 2014-01-30
              • 2016-08-31
              • 2013-11-28
              • 2018-02-26
              • 2015-12-18
              • 2012-02-05
              • 2011-12-16
              • 2013-04-17
              • 1970-01-01
              相关资源
              最近更新 更多