part1:首页实现-头部搜索框
首先新建一个头部布局:main_search.xml在里面定义头部搜索的内容
具体代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#c23"
android:gravity="center"
android:orientation="horizontal">
<!--扫一扫-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:background="@mipmap/main_scan" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="扫一扫" />
</LinearLayout>
<!--搜索-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@mipmap/main_header_sourch"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:background="@mipmap/search" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:hint="目的地/景点/酒店/门票" />
</LinearLayout>
<!--消息-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:background="@mipmap/news" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="消息" />
</LinearLayout>
</LinearLayout>
然后再fragment_main.xml中加载进去
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/main_search">
</include>
即可。
Part2:头部广告页的实现
使用ViewPager,来绑定适配器,适配器中是存放你要展示的数据。
在fragment_main中加个适配器布局
<android.support.v4.view.ViewPager
android:id="@+id/main_vPager_ad"
android:layout_width="match_parent"
android:layout_height="120dp">
</android.support.v4.view.ViewPager>
主界面视图中 绑定ViewPager和适配器
/**
* 主界面视图
*/
public class MainFragment extends Fragment {
//传进的广告图片的数组
protected int[] icons={R.mipmap.header_pic_ad1,R.mipmap.header_pic_ad2,R.mipmap.header_pic_ad1};
private ViewPager mVpagerHeaderAd;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main,container,false);
}
//在fragment被创建的时候绑定ViewPager
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mVpagerHeaderAd=getView().findViewById(R.id.main_vPager_ad);
//ViewPager绑定适配器 和数据
mVpagerHeaderAd.setAdapter(new MainHeaderAdAdapter(getActivity(), DataUtil.getHeaderInfo(getActivity(),icons)));
}
}
新建一个MainHeaderAdAdapter适配器类继承适配器
public class MainHeaderAdAdapter extends PagerAdapter {
protected Context context;
protected List<ImageView> images;//成员变量
//构造函数赋值操作 把参数值赋值给成员变量
public MainHeaderAdAdapter(Context context, List<ImageView> images) {
this.context = context;
this.images = images;//
}
@Override
public int getCount() {
return null != images ? images.size() : 0;//如果集合不为空,则返回集合大小,否则返回0
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(images.get(position));//给容器添加图片
return images.get(position);//返回图片
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(images.get(position));//移除view
}
}
绑定适配器数据的工具类
/**
* 绑定数据的工具类
*/
public class DataUtil {
//第一个参数是上下文,第二个参数是图标数组
public static List<ImageView> getHeaderInfo(Context context,int icons[]){
List<ImageView> datas=new ArrayList<>();
for(int i=0;i<icons.length;i++){
ImageView icon=new ImageView(context);
//ScaleType=CENTER_CROP、如果原图size小于ImageView的size
// 则按比例拉升原图的宽和高,填充ImageView居中显示。
icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
icon.setImageResource(icons[i]);
datas.add(icon);}
return datas;//返回图片数据
}
}
到这里就完成了
part3:首页实现-主菜单实现
整体思路:
首先,在xml布局通scrollview中嵌套一个RecycleView来回收复原的视图并创建一个要显示的View(item_main_menu.xml)
自定义RecycleView继承RecycleView.Adapter,重写多个方法,绑定数据和视图
然后在Fragment_Main绑定RecycleView的Adapter适配器装数据
最后通过自定义RecycView调用setLayoutManager(new GridLayoutManager(getActivity(),4))方法,展示成网格状的菜单,
呈每行4列的形状。
什么是RecyclerView?
RecyclerView是support-v7包中的新组件,是一个强大的滑动组件
与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字Recyclerview即回收view也可以看出。
RecyclerView.Adapter、RecyclerView和RecyclerView.ViewHolder三者的区别
- ViewGroup是一个可以包含很多个子View的类,每一个列表项都是作为一个View子对象显示的,每个View可以是简单的也可以是复杂的。
- 这里假设每个View都是一个TextView,而且一个屏幕可以显示10个TextView,现在有上百个TextView要显示,那是不是意味着要准备上百个TextView呢?不是,这里涉及到回收利用的思想,并且已经封装成了RecylerView类。RecyclerView可以创建刚刚好充满屏幕的10个视图,用户滑动屏幕切换视图时,上一个视图就被回收利用并且加载下一个将要显示的视图。
- RecyclerView的任务就是回收和定位屏幕上的View。
- 列表项View显示数据涉及Adapter和ViewHolder。
- ViewHolder只做一件事,就是容纳View视图。
- RecyclerView并不会创建视图,它创建的是ViewHolder,而ViewHolder分别引用着一个个itemView。不过RecyclerView自己也是不直接创建ViewHolder的,这个任务是adapter完成的。Adapter是一个控制器(适配器)对象,从模型层获取数据,然后提供给RecyclerView显示,起到桥梁的作用。
- Adapter负责任务有2个:
- 1.创建必要的ViewHolder;
- 2.绑定ViewHolder到模型层数据。.
- 创建Adapter,首先要定义RecyclerView.Adapter,然后由他封装获取的数据。
- RecyclerView要视图时,就会去找它的Adapter:
- 1)先调用Adapter的getItemCount()方法,询问数组列表中的对象数量。
- 2)RecyclerView调用adapter的createViewHolder(ViewGroup,int)方法创建ViewHolder以及ViewHolder要显示的视图。
- 3)RecyclerView会传入ViewHolder及其位置,调用onBindViewHolder(ViewGroup,int)方法。adapter会找到目标位置的数据并且绑定到ViewHolder视图上。绑定就是使用模型数据填充视图。
- 三个过程完成后,RecyclerView就能在屏幕上显示View了,另外createViewHolder以及onBindViewHolder使用并不频繁。创建了够用的ViewHolder就停止调用了。然后会自动回收旧的ViewHolder来节约时间和节省内存。
代码实现:
在fragment_main.xml中添加RecycleView,如果没有要导入依赖包File->project structure->选中你要添加到的modules->dependencies->+号->添加Libray dependencies->
<android.support.v7.widget.RecyclerView
android:id="@+id/recycleview_maim_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
Adapter配置部分:
- 1-item_main_menu.xml 定义ViewHolder 容纳的View视图
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/img_menu_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@mipmap/menu_car"/>
<TextView
android:id="@+id/name_menu_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="车票"
android:textColor="#000000"/>
</LinearLayo
- 2-新建集合来封装每个一个Menu的信息
/**
* 集合
*/
public class Menu {
public int icon;//菜单图标
public String menuName;//菜单名称
public Menu(int icon, String menuName) {
this.icon = icon;
this.menuName = menuName;
}
}
- 3-在绑定数据的工具类DataUtil.java 写一个传入数据的方法
//主菜单的数据
public static List<Menu> getMainMenu(int icons[],String names[] ){
List<Menu> menus= new ArrayList<>();
for(int i=0;i<icons.length;i++){
Menu menu=new Menu(icons[i],names[i]);
menus.add(menu);
}
return menus;
}
- 4-string.xml中写字符串数组给Adapter提供数据图标名称数据
<string-array name="main_menu">
<item>飞机票</item>
<item>住酒店</item>
<item>去旅游</item>
<item>周边游</item>
<item>买门票</item>
<item>火车票</item>
<item>汽车票</item>
<item>领里程</item>
</string-array>
- 5- MainMenuAdapter.java继承RecycleView.Adapter来绑定数据
public class MainMenuAdapter extends RecyclerView.Adapter<MainMenuAdapter.MainMenuViewHolder> {
//成员变量
Context context;
List<Menu> menus;
public MainMenuAdapter(Context context, List<Menu> menus) {
this.context = context;
this.menus = menus;//将传进来的参数赋值给成员变量
}
@Override
//onCreateViewHolder()负责为Item创建视图
public MainMenuViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MainMenuViewHolder(LayoutInflater.from(context).inflate(R.layout.item_main_menu, null));
}
@Override
//onBindViewHolder()负责将数据绑定到Item的视图上
public void onBindViewHolder(MainMenuViewHolder holder, int position) {
Menu menu = menus.get(position);//获取列表数据的第几个数据
holder.mImgMenuIcon.setImageResource(menu.icon);//图标获取数据
holder.mTextMenuName.setText(menu.menuName);//图标名称获取数据
}
@Override
public int getItemCount() {
return null != menus ? menus.size() : 0;//如果menus不为空,返回它的大小,否则返回0
}
class MainMenuViewHolder extends RecyclerView.ViewHolder {
public ImageView mImgMenuIcon;
public TextView mTextMenuName;
public MainMenuViewHolder(View itemView) {
super(itemView);
mImgMenuIcon=itemView.findViewById(R.id.img_menu_icon);
mTextMenuName=itemView.findViewById(R.id.name_menu_icon);
}
}}
6-MainFragment.java中绑定RecycleView的适配器 显示
/**
* 主界面视图
*/
public class MainFragment extends Fragment {
//主菜单的图标数据
protected int[] menuIcons={R.mipmap.menu_airport,R.mipmap.menu_hatol,
R.mipmap.menu_trav, R.mipmap.menu_nearby,
R.mipmap.menu_ticket,R.mipmap.menu_train,
R.mipmap.menu_car,R.mipmap.menu_course };
String[] menusNames;//主菜单图标名称数组
private ViewPager mVpagerHeaderAd;//广告头部
private RecyclerView mRecycleViewMenu;//主菜单
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main,container,false);
}
//在fragment被创建的时候绑定ViewPager
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//获取主菜单名称数组的数据
menusNames=getActivity().getResources().getStringArray(R.array.main_menu);
//recycleView的绑定
mRecycleViewMenu=getView().findViewById(R.id.recycleview_maim_menu);
//主菜单设置适配器()
//布局样式(网格样式(当前activity,4列))
mRecycleViewMenu.setLayoutManager(new GridLayoutManager(getActivity(),4));
mRecycleViewMenu.setAdapter(new MainMenuAdapter(getActivity(),DataUtil.getMainMenu(menuIcons,menusNames)));
}
}
到这里就完成啦