如何在recycleview 的gridlayout 中设置自动列?
How to set auto column in gridlayout of recycleview?
我正在尝试在 recycleview 的 gridlayout 上存档自动设置的列大小。我找到了它的代码,但我是 android 的新手,所以我现在不知道如何在我的片段 class 中实现它。请指导我如何实现它
1) 基础片段 class
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 的 autosetcolumn 方法
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);
}}
我们扩展 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
中,我们让超级class进行测量,然后从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.
我正在尝试在 recycleview 的 gridlayout 上存档自动设置的列大小。我找到了它的代码,但我是 android 的新手,所以我现在不知道如何在我的片段 class 中实现它。请指导我如何实现它
1) 基础片段 class
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 的 autosetcolumn 方法
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);
}}
我们扩展 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
中,我们让超级class进行测量,然后从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.