Android:GridLayout大小和View.GONE行为

lnlaulya  于 2023-04-18  发布在  Android
关注(0)|答案(5)|浏览(147)

我想做一个GridLayout,当它的一个孩子的Visibility被设置为GONE时,它会被下一个孩子替换。

这不是作业我自己画的是为了更好地解释。
我可以让布局在列数和宽度等方面都正常工作。只是GridLayout的默认GONE行为使子元素消失而不是被替换,就像其他布局一样。
我确实尝试了很多东西,我尝试搜索SO和谷歌,但我似乎不能解决这个问题。这将是我正在开发的应用程序最方便的布局。有没有办法在布局中做到这一点,而不必通过编程来做到这一点?或者两者兼而有之?

7dl7o3gd

7dl7o3gd1#

如果你不需要将视图再次变为可见,你可以通过从GridLayout中删除视图来解决这个问题。

private void hideView(View view) {
    GridLayout gridLayout = (GridLayout) view.getParent();
    for (int i = 0; i <  gridLayout.getChildCount(); i++) {
        if (view == gridLayout.getChildAt(i)) {
            gridLayout.removeViewAt(i);
            break;
        }
    }
}
j8yoct9x

j8yoct9x2#

解决方案是使用RecyclerView沿着GridLayoutManager。关键是通过使用notifyItemRemoved通知适配器有关已删除项目的更改。RecyclerViews中有很多自定义空间,例如消失项目的漂亮动画,屏幕上剩余项目的重新排列,您可以应用所有这些自定义和额外的逻辑删除的项目需要为您的特定问题。
活动

public class MainActivity extends AppCompatActivity {
    RecyclerView recyclerView;

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

        List<String> dataSet = getSampleDataSet();
        recyclerView = (RecyclerView) findViewById(R.id.grid);
        recyclerView.setAdapter(new MyAdapter(dataSet));
        recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(), 2));
    }

    private List<String> getSampleDataSet() {
        List strings = new ArrayList();
        strings.add("one");
        strings.add("two");
        strings.add("three");
        strings.add("four");
        strings.add("five");
        strings.add("six");

        return strings;
    }
}

适配器

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    List<String> dataSet;


    public MyAdapter(List<String> dataSet) {
        this.dataSet = dataSet;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        TextView tileView = (TextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
        MyViewHolder myViewHolder = new MyViewHolder(tileView);

        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        holder.view.setText(dataSet.get(position));

        holder.view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dataSet.remove(position);
                notifyItemRemoved(position); // this notifies the adapter about item being removed
            }
        });

    }

    @Override
    public int getItemCount() {
        return dataSet.size();
    }
}

class MyViewHolder extends RecyclerView.ViewHolder {
    TextView view;

    public MyViewHolder(TextView itemView) {
        super(itemView);
        view = itemView;
    }
}

活动布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/grid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

网格项

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridItem"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/colorPrimary"
    android:textColor="@android:color/white"
    android:gravity="center"
    android:text="Tile"/>

之前的结果:

点击4后。在实际设备上,您将能够看到此操作的漂亮框架动画。

lpwwtiir

lpwwtiir3#

解决与以下相同的问题:

package ua.vsgroup.widgets;

import android.content.Context;
import android.support.v7.widget.GridLayout;
import android.util.AttributeSet;
import android.view.View;

public class vsGridLayout extends GridLayout {

    View[] mChild = null;

    public vsGridLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public vsGridLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public vsGridLayout(Context context) {
        this(context, null);
    }

    private void arrangeElements() {

        mChild = new View[getChildCount()];
        for (int i = 0; i < getChildCount(); i++) {
            mChild[i] = getChildAt(i);
        }

        removeAllViews();
        for (int i = 0; i < mChild.length; i++) {
            if (mChild[i].getVisibility() != GONE)
                addView(mChild[i]);
        }
        for (int i = 0; i < mChild.length; i++) {
            if (mChild[i].getVisibility() == GONE)
                addView(mChild[i]);
        }

    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

        arrangeElements();
        super.onLayout(changed, left, top, right, bottom);

    }

}
o8x7eapl

o8x7eapl4#

基于this的答案。谢谢。
创建自定义GridLayout小部件。

package com.isolpro.pricelist.custom;    

public class RearrangingGridLayout extends GridLayout {
  private final List<View> views = new ArrayList<>();

  public RearrangingGridLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  public RearrangingGridLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public RearrangingGridLayout(Context context) {
    this(context, null);
  }

  private void arrangeElements() {
    removeAllViews();

    for (int i = 0; i < views.size(); i++) {
      if (views.get(i).getVisibility() != GONE)
        addView(views.get(i));
    }
  }

  public void saveViews() {
    for (int i = 0; i < getChildCount(); i++) {
      views.add(getChildAt(i));
    }
  }

  public void hideViewAtIndex(int index) {
    if (index >= 0 && index < views.size()) {
      views.get(index).setVisibility(GONE);
      arrangeElements();
    }
  }

  public void showViewAtIndex(int index) {
    if (index >= 0 && index < views.size()) {
      views.get(index).setVisibility(VISIBLE);
      arrangeElements();
    }
  }
}

下面是如何使用它:
在绑定(呈现)GridLayout后保存它的所有子级,使用以下代码

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

    RearrangingGridLayout rglPrices = findViewById(R.id.rglPrices);

    rglPrices.saveViews();
  }

现在,为了隐藏你的视野

rglPrices.hideViewAtIndex(indexOfView);

同样地,为了展示你的观点

rglPrices.showViewAtIndex(indexOfView);

你完了!
在我的项目中,保留子元素的位置是很重要的,所以我使用了index。你可以通过更新show和hide函数,轻松地修改代码来处理其他东西,比如view id。

a64a0gku

a64a0gku5#

这是很好的answer
对于那些想要传递视图而不是索引到函数中的人。

public void hideView(View child) {
    for (int i = 0; i < views.size(); i++) {
        if (views.get(i).getId() == child.getId()) {
            views.get(i).setVisibility(GONE);
            arrangeElements();
            break;
        }
    }
}

public void showView(View child) {
    for (int i = 0; i < views.size(); i++) {
        if (views.get(i).getId() == child.getId()) {
            views.get(i).setVisibility(VISIBLE);
            arrangeElements();
        }
    }
}

相关问题