你可以在stggeredListView中添加两种类型的项目吗?

时间:2015-05-12 15:04:52

标签: android staggered-gridview

我的应用使用

  

com.etsy.android.grid.StaggeredGridView

我有一个适配器,用自定义项填充交错网格。我现在想要为该网格添加另一个自定义项。可以这样做吗?

我有2个自定义项xmls和2个layoutadapters。如何将两者都添加到交错网格中?我尝试使用addVeiw()但它在staggeredGridview中不可用。也许我应该只使用1个适配器?

我会将代码保持在最低限度,但询问您是否想要查看更多内容。

import org.apache.http.NameValuePair;

public class GamesSummary_Fragment_Activity extends FragmentActivity
{
    private ArrayList<String[]> loginTilesData;
    private static final String TAG = "StaggeredGridActivityFragment";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        final FragmentManager fm = getSupportFragmentManager();

        // Create the list fragment and add it as our sole content.
        if (fm.findFragmentById(android.R.id.content) == null) {
            final StaggeredGridFragment fragment = new StaggeredGridFragment();
            fm.beginTransaction().add(android.R.id.content, fragment).commit();
        }
    }

    private class StaggeredGridFragment extends Fragment implements AbsListView.OnScrollListener, AbsListView.OnItemClickListener
    {
                private StaggeredGridView stagggeredGridView;
                private boolean mHasRequestedMore;
                private TilesAdapter_Summary mAdapter;

                @Override
                public void onCreate(final Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setRetainInstance(true);
                }

                @Override
                public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
                    return inflater.inflate(R.layout.activity_sgv, container, false);
                }

                @Override
                public void onActivityCreated(final Bundle savedInstanceState) {
                    List<NameValuePair> params = new ArrayList<NameValuePair>();

                    //Encapsulate all within a post create from a async task or call a blocking http call
                    super.onActivityCreated(savedInstanceState);

                    stagggeredGridView = (StaggeredGridView) getView().findViewById(R.id.grid_view);

                    if (mAdapter == null) {
                        mAdapter = new TilesAdapter_Summary(getActivity(), R.id.summary1_value);
                    }

                    for (String[] data : loginTilesData) {
                        mAdapter.add(data); //Add each loginTilesData TileAdapter element to an mAdapter where it will be further broken down and used by the TileAdapter
                    }
                //Add controls item layout
                final LayoutInflater layoutInflator = getActivity().getLayoutInflater();
                View viewControls = layoutInflator.inflate(R.layout.grid_item_controls, null);
                staggeredGridView.addView(viewControls, 1); //THIS FAILS WITH ERROR SAYING PARENT CLASS CANT DO 'addVeiw()

                    stagggeredGridView.setAdapter(mAdapter);
                    stagggeredGridView.setOnScrollListener(this);
                    stagggeredGridView.setOnItemClickListener(this);
                }
}

public class TilesAdapter_Summary extends ArrayAdapter<String[]> {
    private static final String TAG = "TilesAdapter";

    static class ViewHolder {
        ImageView summary_image;
        TextView summary1_label;
        TextView summary2_label;

    }

adapter_summary class

    private final LayoutInflater mLayoutInflater;
    private final Random mRandom;
    private final ArrayList<Integer> mBackgroundColors;
    private static final SparseArray<Double> sPositionHeightRatios = new SparseArray<Double>();

    public TilesAdapter_Summary(final Context context, final int textViewResourceId) {
        super(context, textViewResourceId);
        mLayoutInflater = LayoutInflater.from(context);
        mRandom = new Random();
        mBackgroundColors = new ArrayList<Integer>();
        mBackgroundColors.add(R.color.green);
        mBackgroundColors.add(R.color.blue);
        mBackgroundColors.add(R.color.yellow);
    }

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent)
    {
                //Init the Viewholder with the controls we want to populate
            ViewHolder vh;
            if (convertView == null) {
                convertView = mLayoutInflater.inflate(R.layout.grid_item_summary, parent, false);
                vh = new ViewHolder();
                vh.summary_image = (ImageView) convertView.findViewById(R.id.summary_image);
                vh.summary1_label = (TextView) convertView.findViewById(R.id.summary1_label);
                vh.summary2_label = (TextView) convertView.findViewById(R.id.summary2_label);

                convertView.setTag(vh);
            } else {
                vh = (ViewHolder) convertView.getTag();
            }

            double positionHeight = getPositionRatio(position);
            int backgroundIndex = position >= mBackgroundColors.size() ?
                    position % mBackgroundColors.size() : position;

            convertView.setBackgroundResource(mBackgroundColors.get(backgroundIndex));

            Log.d(TAG, "getView position:" + position + " h:" + positionHeight);

            String[] tileControlValues = getItem(position); //Get this TileAdapters item and split it up

            //Assign the tileControlValues to controls
            vh.summary_header.setText(tileControlValues[0]);
            vh.summary_subheader.setText(tileControlValues[1]);
            vh.summary1_label.setText(tileControlValues[2]);
            vh.summary1_value.setText(tileControlValues[3]);
            vh.summary2_label.setText(tileControlValues[4]);
            vh.summary2_value.setText(tileControlValues[5]);

        return convertView;
    }

    private double getPositionRatio(final int position) {
        double ratio = sPositionHeightRatios.get(position, 0.0);
        // if not yet done generate and stash the columns height
        // in our real world scenario this will be determined by
        // some match based on the known height and width of the image
        // and maybe a helpful way to get the column height!
        if (ratio == 0) {
            ratio = getRandomHeightRatio();
            sPositionHeightRatios.append(position, ratio);
            Log.d(TAG, "getPositionRatio:" + position + " ratio:" + ratio);
        }
        return ratio;
    }

    private double getRandomHeightRatio() {
        return (mRandom.nextDouble() / 2.0) + 1.0; // height will be 1.0 - 1.5 the width
    }
}

2 个答案:

答案 0 :(得分:0)

根据您要解决的问题类型,一个合适的替代方案是考虑将RecyclerView与StaggeredGridLayoutManager一起使用,并自定义适配器以使用2种(或更多,如果需要)类型的ViewHolders,允许每一种他们拥有自己的布局。

更新

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
    if(getItemViewType(position) == 1) {
        // work with ViewHolderTypeOne
    } else if(getItemViewType(position) == 2) {
        // work with ViewHolderTypeTwo
    }
}

@Override
public int getItemViewType(int i) {
    // View Types: 1 - view type one, 2 - view type two, determined by position i in grid
    if(i == 0) {
        return 1;
    } else {
        return 2;
    }
}

class ViewHolderTypeOne extends ViewHolder {
    public viewOneAttrOne;
    public viewOneAttrTwo;
}

class ViewHolderTypeTwo extends ViewHolder {
    public viewTwoAttrOne;
    public viewTwoAttrTwo;
    public viewTwoAttrThree;
}

答案 1 :(得分:0)

得到了答案,不一定是最好的答案,所以我可以稍稍打开......

我添加了将新项目xml控件合并到旧版本中,因此只有一个,然后我找出将项目添加到网格时显示的控件。在一个网格中给出两个差异项目的印象....当将项目添加到页面时...我向字符串数组添加一个新元素,触发要构建的新项目xml - 我认识到这个新元素需要显示差异控制,所以我把原来的控件看不见,新的控件可见,

    if (tileControlValues[0].equals("controls"))
    {
        vh.layout_summary.setVisibility(View.INVISIBLE);
        vh.layout_controls.setVisibility(View.VISIBLE);
    }
    else
    {
        vh.summary_header.setText(tileControlValues[0]);
        vh.summary_subheader.setText(tileControlValues[1]);
        vh.summary1_label.setText(tileControlValues[2]);
        vh.summary1_value.setText(tileControlValues[3]);
        vh.summary2_label.setText(tileControlValues[4]);
        vh.summary2_value.setText(tileControlValues[5]);