如何在recycleview的gridlayout中设置自动列?

时间:2016-04-19 08:07:57

标签: android android-recyclerview android-gridlayout gridlayoutmanager

我正在尝试在recycleview中的gridlayout上归档自动设置列大小。我找到了一个代码,但我是android的新手,所以我现在不知道如何在我的片段类中实现它。请指导我如何实施它

1)基础片段类

public class BaseFragment extends android.app.Fragment implements RecycleAdapter.GetDataFromAdapter {

    @Bind(R.id.recyclerView) RecyclerView recyclerView;
    private static final String STATE_MOVIES = "state_movies";
    private View rootView = null;
    private ServiceManager serviceManager;
    private RecycleAdapter recyclerAdapter;
    private MovieResponse movieResponse;
    private List<Results> resultsList;

    private Results results;
    private OnFragmentInteractionListener mListener;

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

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList(STATE_MOVIES, (ArrayList<? extends Parcelable>) resultsList);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.High_rated:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    makeService("TOP");
                    return true;
                }
            case R.id.most_Popular:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    makeService("POPULAR");
                    return true;
                }
            case R.id.favoriteList:
                if(item.isChecked()){
                    item.setChecked(false);
                }else{
                    item.setChecked(true);
                    Intent intent=new Intent(getActivity(), FavoriteActivity.class);
                    startActivity(intent);
                    return true;
                }
        }
        return super.onOptionsItemSelected(item);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_base, container, false);
        ButterKnife.bind(this,rootView);
        resultsList=new ArrayList<Results>();
        configRecycleView();

        if (savedInstanceState==null){
            makeService("POPULAR");
        }else{
            resultsList=savedInstanceState.getParcelableArrayList(STATE_MOVIES);
            recyclerAdapter.addMovieList(resultsList);
        }
        return rootView;
    }

    private void configRecycleView() {
        recyclerView.setHasFixedSize(true);
        recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());

        recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),
                2));
        recyclerAdapter = new RecycleAdapter(getActivity(), BaseFragment.this
        );
        recyclerView.setAdapter(recyclerAdapter);
    }

    private void makeService(String query){
        serviceManager = new ServiceManager();
        Call<MovieResponse> listCall;
        if (query=="TOP") {
            listCall= serviceManager.getJSONData().getTopMovies();
        }else{
            listCall= serviceManager.getJSONData().getPopMovies();
        }
        listCall.enqueue(new Callback<MovieResponse>() {
            @Override
            public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
                if (response.isSuccessful()) {
                    Results[] results = response.body().getResults();
                    resultsList = new ArrayList<Results>(Arrays.asList(results));
                    recyclerAdapter.addMovieList(resultsList);
                    Toast.makeText(getActivity(), "Data Fatch", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<MovieResponse> call, Throwable t) {
                Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    public void onCurrentMovie(Results currentMovie) {
        mListener.onFragmentInteraction(currentMovie);
    }

    @Override
    public void onAttach(Activity context) {
        super.onAttach(context);

        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    public interface OnFragmentInteractionListener {
        void onFragmentInteraction(Results result);
    }
}

2)在recycleview中对gridlayout进行自动设置列的方法

public class VarColumnGridLayoutManager extends GridLayoutManager {

private int minItemWidth;

public VarColumnGridLayoutManager(Context context, int minItemWidth) {
    super(context, 1);
    this.minItemWidth = minItemWidth;
}

@Override
public void onLayoutChildren(RecyclerView.Recycler recycler,
        RecyclerView.State state) {
    updateSpanCount();
    super.onLayoutChildren(recycler, state);
}

private void updateSpanCount() {
    int spanCount = getWidth() / minItemWidth;
    if (spanCount < 1) {
        spanCount = 1;
    }
    this.setSpanCount(spanCount);
}}

1 个答案:

答案 0 :(得分:3)

我们扩展RecyclerView以访问其宽度。至于每个项目的宽度,当GridView具有android:numColumns="auto_fit"时,它使用android:columnWidth来计算列数。让我们重用该属性。

private void init(Context context, AttributeSet attrs) {
  if (attrs != null) {
    int[] attrsArray = {
        android.R.attr.columnWidth
    };
    TypedArray array = context.obtainStyledAttributes(
      attrs, attrsArray);
    columnWidth = array.getDimensionPixelSize(0, -1);
    array.recycle();
  }

  manager = new GridLayoutManager(getContext(), 1);
  setLayoutManager(manager);
}

在构造函数中,我们读取android:columnWidth的值并将其保存在成员变量中。稍后在onMeasure中将使用它来确定跨度计数。

即使我们将onMeasure设置跨度计数,如果我们等到那时定义GridLayoutManager,应用程序也会崩溃,所以我们也在这里创建一个,跨度计数为1。

onMeasure中,我们要求超类执行测量,然后从getMeasuredWidth获取值来计算跨度计数。

protected void onMeasure(int widthSpec, int heightSpec) {
  super.onMeasure(widthSpec, heightSpec);
  if (columnWidth > 0) {
    int spanCount = Math.max(1, getMeasuredWidth() / columnWidth);
    manager.setSpanCount(spanCount);
  }
}

完整项目样本here