先看效果
由于设备有限,不能录制视频
接下来我们就来实现这个效果
其中条目中的图片使用的也是RecylerView,也就是这个使用了两个RecylerView相互嵌套实现的
类与布局之间的关系
使用到的类
1.NearByFragment
2.NearbyListAdapter
3.OnlyImgAdapter
使用的布局
1.nearby_fragment_layout
2.nearby_item_layout
3.only_image_com_layout
这里的类与布局是相对应的,第一个类使用的布局是第一个,以此类推
nearby_fragment_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--顶部-->
<LinearLayout
android:padding="@dimen/top_theme_pad"
android:orientation="horizontal"
android:background="@color/theme_clo"
android:layout_width="match_parent"
android:layout_height="@dimen/top_theme_height">
<LinearLayout
android:id="@+id/nearby_search"
android:layout_gravity="center"
android:paddingRight="@dimen/top_theme_pad"
android:paddingLeft="@dimen/top_theme_pad"
android:layout_marginLeft="15dp"
android:background="@drawable/search_border"
android:layout_width="match_parent"
android:layout_height="@dimen/editText_size">
<ImageView
android:src="@drawable/search_write"
android:layout_gravity="center"
android:layout_width="@dimen/search_icon_size"
android:layout_height="@dimen/search_icon_size"/>
<EditText
android:id="@+id/home_search"
android:background="@drawable/edit_none"
android:padding="10dp"
android:textColor="@color/search_hint_col"
android:layout_width="match_parent"
android:layout_height="@dimen/editText_size"
android:hint="@string/search_hint"/>
</LinearLayout>
</LinearLayout>
<!--发布-->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_weight="1"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/nearby_newRelease"
android:gravity="center"
android:textColor="@color/theme_black"
android:textSize="@dimen/item_text_size"
android:text="@string/new_release"
android:layout_width="match_parent"
android:layout_height="@dimen/top_theme_height"/>
<View
android:id="@+id/nearby_newReleaseLine"
android:background="@color/theme_clo"
android:layout_width="match_parent"
android:layout_height="@dimen/view_size"/>
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/nearby_nearRelease"
android:gravity="center"
android:textColor="@color/theme_black"
android:textSize="@dimen/item_text_size"
android:text="@string/near_release"
android:layout_width="match_parent"
android:layout_height="@dimen/top_theme_height"/>
<View
android:id="@+id/nearby_nearReleaseLine"
android:visibility="gone"
android:background="@color/theme_clo"
android:layout_width="match_parent"
android:layout_height="@dimen/view_size"/>
</LinearLayout>
</LinearLayout>
<include layout="@layout/line_spilt_10_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/nearby_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
nearby_item_layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:padding="@dimen/top_theme_pad"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/nearby_item_click"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/nearby_item_img"
android:src="@drawable/default_img"
android:layout_width="@dimen/top_icon_size"
android:layout_height="@dimen/top_icon_size"/>
<LinearLayout
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/top_theme_pad"
android:layout_toRightOf="@+id/nearby_item_img"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/nearby_item_name"
android:text="@string/default_name"
android:textColor="@color/theme_black"
android:textSize="@dimen/item_text_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/nearby_item_phone"
android:text="@string/default_phone"
android:textColor="@color/theme_black"
android:textSize="@dimen/fab_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView
android:id="@+id/nearby_item_price"
android:layout_centerVertical="true"
android:text="@string/default_price"
android:layout_alignParentRight="true"
android:textColor="@color/price_col"
android:textSize="@dimen/item_text_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
<View
android:layout_marginBottom="@dimen/top_theme_pad"
android:layout_marginTop="@dimen/top_theme_pad"
android:background="@color/line_thin"
android:layout_width="match_parent"
android:layout_height="@dimen/view_size"/>
<TextView
android:id="@+id/nearby_item_detail"
android:text="@string/default_detail"
android:maxLines="2"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/nearby_item_imgList"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
only_image_com_layout
这里只有一个ImageView,没有什么难度,只需要注意设置图片显示的最大宽高与最小宽高,方便适配不同大小的图片尺寸,也可以通过代码来控制,我这里没写,使用的是默认的
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="@dimen/view_size"
android:gravity="center" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/only_img_img"
android:layout_marginBottom="@dimen/top_theme_pad"
android:minHeight="@dimen/only_img_min_size"
android:minWidth="@dimen/only_img_min_size"
android:maxWidth="@dimen/only_img_max_size"
android:maxHeight="@dimen/only_img_max_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
布局就是这样的
实现
编写NearbyListAdapter
在RecylerView中,使用的适配器与ListView等的适配器不同,这里需要使用RecylerView中的适配器,需要继承RecylerView.Adapter,这个适配器有一个泛型,用于指定使用的Holder类,自定义的Holder类也需要继承RecylerView中的ViewHolder类,Holder类用于获取控件,大部分一样,我这里就给出一个就OK,我这里使用的是内部类
public RelativeLayout mNearbyItemClick;
public ImageView mNearbyItemImg;
public TextView mNearbyItemName;
public TextView mNearbyItemPhone;
public TextView mNearbyItemPrice;
public TextView mNearbyItemDetail;
public RecyclerView mNearbyItemImglist;
public ViewHolder(@NonNull View itemView) {
super(itemView);
mNearbyItemClick = itemView.findViewById(R.id.nearby_item_click);
mNearbyItemImg = itemView.findViewById(R.id.nearby_item_img);
mNearbyItemName = itemView.findViewById(R.id.nearby_item_name);
mNearbyItemPhone = itemView.findViewById(R.id.nearby_item_phone);
mNearbyItemPrice = itemView.findViewById(R.id.nearby_item_price);
mNearbyItemDetail = itemView.findViewById(R.id.nearby_item_detail);
mNearbyItemImglist = itemView.findViewById(R.id.nearby_item_imgList);
}
继承了RecylerView.Adapter后需要实现他的三个方法,onCreateViewHolder()、onBindViewHolder()、getItemCount()
onCreateViewHolder:这个方法用户用户获取View视图并返回给Holder类调用
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
inflter = LayoutInflater.from(mContext).inflate(R.layout.nearby_item_layout, null);
ViewHolder holder = new ViewHolder(inflter);
return holder;
}
onBindViewHolder:这个方法用于绑定数据
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
RoundedCorners roundedCorners = new RoundedCorners(50);
RequestOptions options = new RequestOptions().bitmapTransform(roundedCorners);
Glide.with(mContext).load(R.drawable.default_img).apply(options).into(holder.mNearbyItemImg);
holder.mNearbyItemName.setText(mContext.getResources().getString(R.string.default_name));
holder.mNearbyItemPhone.setText(mContext.getResources().getString(R.string.default_phone));
holder.mNearbyItemPrice.setText(mContext.getResources().getString(R.string.default_price));
holder.mNearbyItemDetail.setText(mContext.getResources().getString(R.string.default_detail));
manager = new GridLayoutManager(mContext, 4);
imgAdapter = new OnlyImgAdapter(mContext, nearbyImgs);
holder.mNearbyItemImglist.setLayoutManager(manager);
holder.mNearbyItemImglist.setAdapter(imgAdapter);
holder.mNearbyItemImglist.setNestedScrollingEnabled(false);
holder.mNearbyItemClick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clickListener.ItemOnClickListener(position);
}
});
}
getItemCount:这个方法用于返回当前数据条数,有多少条数据就有多少个item
public int getItemCount() {
return nearbyImgs.length;
}
每一个适配器的写法基本一致。之前RecylerView有item的点击事件,但是后面用的时候发现没有这个方法了,所以就的自己暴露一个接口去给外部写点击事件,
public interface ItemClickListener {
void ItemOnClickListener(int position);
}
点击事件的使用
申明点击接口,并在构造方法中让外部去实现
public SudukuIconAdapter(Context mContext, Integer[] onlyImage, String[] imageString, ItemClickListener clickListener) {
this.clickListener = clickListener;
this.mContext = mContext;
this.onlyImage = onlyImage;
ImageString = imageString;
}
在item中写最大一个控件的点击事件,然后调用接口的方法,并把当前点击的position传递出去
holder.mOnlyImageClick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clickListener.ItemOnClickListener(position);
}
});
在外部实例化适配器时会去实现暴露接口中的方法,这样就可以拿到item的点击事件
typeAdapter = new ComTypeAdapter(getContext(), comTypes,new ItemClickListener() {
@Override
public void ItemOnClickListener(int position) {
Toast.makeText(getContext(), position+"", Toast.LENGTH_SHORT).show();
}
});
这些写好了之后发现两个RecylerView嵌套会导致滑动冲突
解决方法就是给不需要滑动的RecylerView设置这个方法就可以了
holder.mNearbyItemImglist.setNestedScrollingEnabled(false);
最后把代码给出来
NearByFragment
public class NearByFragment extends Fragment {
private LinearLayout mNearbySearch;
private EditText mHomeSearch;
private TextView mNearbyNewrelease;
private View mNearbyNewreleaseLine;
private TextView mNearbyNearrelease;
private View mNearbyNearreleaseLine;
private RecyclerView mNearbyList;
public RecyclerView.LayoutManager layoutManager;
public NearbyListAdapter listAdapter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.nearby_fragment_layout, null);
initView(view);
return view;
}
public boolean isBottom = false;
public boolean isTop = true;
public float lastValue = 0;
private void initView(View view) {
mNearbySearch = view.findViewById(R.id.nearby_search);
mHomeSearch = view.findViewById(R.id.home_search);
mNearbyNewrelease = view.findViewById(R.id.nearby_newRelease);
mNearbyNewreleaseLine = view.findViewById(R.id.nearby_newReleaseLine);
mNearbyNearrelease = view.findViewById(R.id.nearby_nearRelease);
mNearbyNearreleaseLine = view.findViewById(R.id.nearby_nearReleaseLine);
mNearbyList = view.findViewById(R.id.nearby_list);
/*使用网格布局,第一个参数上下文对象,第二参数一行显示几个item*/
layoutManager = new GridLayoutManager(getContext(), 1);
listAdapter = new NearbyListAdapter(getContext(), new Integer[]{R.drawable.default_img, R.drawable.yhh2, R.drawable.yhh3, R.drawable.yhh4, R.drawable.yhh2, R.drawable.yhh3, R.drawable.yhh4}, new ItemClickListener() {
@Override
public void ItemOnClickListener(int position) {
Toast.makeText(getContext(), position + "", Toast.LENGTH_SHORT).show();
}
});
mNearbyList.setLayoutManager(layoutManager);
mNearbyList.setAdapter(listAdapter);
mNearbyNewrelease.setEnabled(false);
mNearbyNewrelease.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new DataLoading(getContext(), "加载中...");
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
DataLoading.DialogDismiss();
}
});
}
}).start();
mNearbyNewrelease.setEnabled(false);
mNearbyNearrelease.setEnabled(true);
mNearbyNewreleaseLine.setVisibility(View.VISIBLE);
mNearbyNearreleaseLine.setVisibility(View.GONE);
layoutManager = new GridLayoutManager(getContext(), 1);
listAdapter = new NearbyListAdapter(getContext(), new Integer[]{R.drawable.default_img, R.drawable.yhh2, R.drawable.yhh3, R.drawable.yhh4, R.drawable.yhh2, R.drawable.yhh3, R.drawable.yhh4},new ItemClickListener() {
@Override
public void ItemOnClickListener(int position) {
Toast.makeText(getContext(), position+"", Toast.LENGTH_SHORT).show();
}
});
mNearbyList.setLayoutManager(layoutManager);
mNearbyList.setAdapter(listAdapter);
}
});
mNearbyNearrelease.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new DataLoading(getContext(), "加载中...");
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
DataLoading.DialogDismiss();
}
});
}
}).start();
mNearbyNewrelease.setEnabled(true);
mNearbyNearrelease.setEnabled(false);
mNearbyNewreleaseLine.setVisibility(View.GONE);
mNearbyNearreleaseLine.setVisibility(View.VISIBLE);
layoutManager = new GridLayoutManager(getContext(), 1);
listAdapter = new NearbyListAdapter(getContext(), new Integer[]{R.drawable.default_img, R.drawable.default_img, R.drawable.yhh3, R.drawable.yhh4, R.drawable.yhh2, R.drawable.yhh3, R.drawable.yhh4},new ItemClickListener() {
@Override
public void ItemOnClickListener(int position) {
Toast.makeText(getContext(), position+"", Toast.LENGTH_SHORT).show();
}
});
mNearbyList.setLayoutManager(layoutManager);
mNearbyList.setAdapter(listAdapter);
}
});
new DataLoading(getContext(), "加载中...");
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
DataLoading.DialogDismiss();
}
});
}
}).start();
}
}
NearbyListAdapter
public class NearbyListAdapter extends RecyclerView.Adapter<NearbyListAdapter.ViewHolder> {
public Context mContext;
public Integer[] nearbyImgs;
public View inflter;
public RecyclerView.LayoutManager manager;
public OnlyImgAdapter imgAdapter;
public ItemClickListener clickListener;
public NearbyListAdapter(Context mContext, Integer[] nearbyImgs,ItemClickListener clickListener) {
this.mContext = mContext;
this.nearbyImgs = nearbyImgs;
this.clickListener = clickListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
inflter = LayoutInflater.from(mContext).inflate(R.layout.nearby_item_layout, null);
ViewHolder holder = new ViewHolder(inflter);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
/*设置图片圆角值 使用的是Glide*/
/*implementation 'com.github.bumptech.glide:glide:4.9.0'*/
RoundedCorners roundedCorners = new RoundedCorners(50);
RequestOptions options = new RequestOptions().bitmapTransform(roundedCorners);
Glide.with(mContext).load(R.drawable.default_img).apply(options).into(holder.mNearbyItemImg);
holder.mNearbyItemName.setText(mContext.getResources().getString(R.string.default_name));
holder.mNearbyItemPhone.setText(mContext.getResources().getString(R.string.default_phone));
holder.mNearbyItemPrice.setText(mContext.getResources().getString(R.string.default_price));
holder.mNearbyItemDetail.setText(mContext.getResources().getString(R.string.default_detail));
/*使用网格布局,第一个参数上下文对象,第二参数一行显示几个item*/
/*在这里给图片设置适配器*/
manager = new GridLayoutManager(mContext, 4);
imgAdapter = new OnlyImgAdapter(mContext, nearbyImgs);
holder.mNearbyItemImglist.setLayoutManager(manager);
holder.mNearbyItemImglist.setAdapter(imgAdapter);
holder.mNearbyItemImglist.setNestedScrollingEnabled(false);
holder.mNearbyItemClick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clickListener.ItemOnClickListener(position);
}
});
}
@Override
public int getItemCount() {
return nearbyImgs.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public RelativeLayout mNearbyItemClick;
public ImageView mNearbyItemImg;
public TextView mNearbyItemName;
public TextView mNearbyItemPhone;
public TextView mNearbyItemPrice;
public TextView mNearbyItemDetail;
public RecyclerView mNearbyItemImglist;
public ViewHolder(@NonNull View itemView) {
super(itemView);
mNearbyItemClick = itemView.findViewById(R.id.nearby_item_click);
mNearbyItemImg = itemView.findViewById(R.id.nearby_item_img);
mNearbyItemName = itemView.findViewById(R.id.nearby_item_name);
mNearbyItemPhone = itemView.findViewById(R.id.nearby_item_phone);
mNearbyItemPrice = itemView.findViewById(R.id.nearby_item_price);
mNearbyItemDetail = itemView.findViewById(R.id.nearby_item_detail);
mNearbyItemImglist = itemView.findViewById(R.id.nearby_item_imgList);
}
}
}
OnlyImgAdapter
public class OnlyImgAdapter extends RecyclerView.Adapter<OnlyImgAdapter.ViewHolder> {
public View infter;
public Context mContext;
public Integer[] imgs;
public OnlyImgAdapter(Context mContext, Integer[] imgs) {
this.mContext = mContext;
this.imgs = imgs;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
infter = LayoutInflater.from(mContext).inflate(R.layout.only_image_com_layout, null);
return new ViewHolder(infter);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
RoundedCorners roundedCorners = new RoundedCorners(10);
RequestOptions options = new RequestOptions().bitmapTransform(roundedCorners);
Glide.with(mContext).load(imgs[position]).apply(options).into(holder.mOnlyImg);
holder.mOnlyImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, ImageActivity.class);
intent.putExtra("img", imgs[position]);
mContext.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return imgs.length;
}
public class ViewHolder extends RecyclerView.ViewHolder{
public ImageView mOnlyImg;
public ViewHolder(@NonNull View itemView) {
super(itemView);
mOnlyImg = itemView.findViewById(R.id.only_img_img);
}
}
}