效果图
实现思维
- 首先要处理管理好需要导入的数据,我们这里创建class来处理这些数据并且便于管理它们。
- 创建一个主activity的布局,里面需要一个ListView控件。
- 创建一个class继承GirdView,并且重写它。我们需要取消GirdView布局的滚动,让它显示全部内容
- 创建一个GirdView的布局,里面导入我们重写好GirdView控件。
- 创建GirdView布局里面小图标的布局。
- 创建一个class继承GirdView的适配器,我们需要重写GirdView适配器class
- 创建ListView适配器使用的数据集合的单例class。
- 创建一个class继承ListView的适配器,我们需要重写ListView适配器class
- 在主activity里实例ListView,处理数据,数据导入适配器,ListView设置适配器
代码部分
1.首先要处理管理好需要导入的数据,我们这里创建class来处理这些数据并且便于管理它们。
这里涉及隐私我只贴出部分代码做参考
package com.example.lenovo.mydemoapp.myMoreOptions; import com.example.lenovo.mydemoapp.R; /** * Created by lenovo on 2018/5/22. */ /* 更多选项列表的数据存放class */ public class MoreOptionsData { //沟通组 private static final String mPhoneTitlem_Title_Text = "沟通"; private static final String [] mPhoneTitlem_Content_Text = {"电话","群聊","私聊","倾听","录音","拍照"}; //得到沟通组数据 public static int[] getmPhoneTitlemContent_Image() { return mPhoneTitlem_Content_Image; } public static String[] getmPhoneTitlemContent_Text() { return mPhoneTitlem_Content_Text; } public static String getmPhoneTitlem_Title_Text() { return mPhoneTitlem_Title_Text; } //得到运动组数据 public static int[] getmMovementTitlemContent_Image() { return mMovementTitlem_Content_Image; } public static String[] getmMovementTitlemContent_Text() { return mMovementTitlem_Content_Text; } public static String getmMovementTitlem_Title_Text() { return mMovementTitlem_Title_Text; } //得到设置组数据 public static int[] getmSettingsTitlemContent_Image() { return mSettingsTitlem_Content_Image; } public static String[] getmSettingsTitlemContent_Text() { return mSettingsTitlem_Content_Text; } public static String getmSettingsTitlem_Title_Text() { return mSettingsTitlem_Title_Text; } //得到其他组数据 public static int[] getmOtherTitlemContent_Image() { return mOtherTitlem_Content_Image; } public static String[] getmOtherTitlemContent_Text() { return mOtherTitlem_Content_Text; } public static String getmOtherTitlem_Title_Text() { return mOtherTitlem_Title_Text; } //得到四组数据的数组 public static String[] getTitle_Text_Attrs(){ return new String[] {mPhoneTitlem_Title_Text,mMovementTitlem_Title_Text,mSettingsTitlem_Title_Text,mOtherTitlem_Title_Text}; } public static String[][] getContent_Text_Attrs(){ return new String[][] {mPhoneTitlem_Content_Text,mMovementTitlem_Content_Text,mSettingsTitlem_Content_Text,mOtherTitlem_Content_Text}; } public static int[][] getContent_Image_Attrs(){ return new int[][] {mPhoneTitlem_Content_Image,mMovementTitlem_Content_Image,mSettingsTitlem_Content_Image,mOtherTitlem_Content_Image}; } }
2.创建一个主activity的布局,里面需要一个ListView控件。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.lenovo.mydemoapp.MoreOptions" > <com.example.lenovo.mydemoapp.myLayout.TitleLayout app:titleNameText="显示标题" android:layout_width="match_parent" android:layout_height="wrap_content"> </com.example.lenovo.mydemoapp.myLayout.TitleLayout> <ListView android:id="@+id/MoreOptions_ListView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="20dp" android:dividerHeight="20dp" android:divider="@color/colorWhite"> </ListView> </LinearLayout>
3.创建一个class继承GirdView,并且重写它。我们需要取消GirdView布局的滚动,让它显示全部内容
package com.example.lenovo.mydemoapp.myMoreOptions; import android.content.Context; import android.util.AttributeSet; import android.widget.GridView; /** * Created by lenovo on 2018/5/23. */ public class NoScrollGridView extends GridView { public NoScrollGridView(Context context, AttributeSet attrs) { super(context, attrs); } public NoScrollGridView(Context context) { super(context); } public NoScrollGridView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //核心在此 int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 3, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
4.创建一个GirdView的布局,里面导入我们重写好GirdView控件。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/input_box_background"> <TextView android:id="@+id/MoreOptions_GridView_TitleName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题名称" android:textSize="@dimen/BigTextSize" android:textColor="@color/colorBlue"/> <com.example.lenovo.mydemoapp.myMoreOptions.NoScrollGridView android:id="@+id/MoreOptions_GridView" android:numColumns="3" android:stretchMode="columnWidth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:horizontalSpacing="20dp" android:verticalSpacing="20dp" android:layout_marginTop="20dp"> </com.example.lenovo.mydemoapp.myMoreOptions.NoScrollGridView> </LinearLayout>
5.创建GirdView布局里面小图标的布局。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp"> <ImageView android:id="@+id/more_options_grid_view_subclass_ImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/ic_funciton_shutdown"/> <TextView android:id="@+id/more_options_grid_view_subclass_TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="图标名称" android:textColor="@color/colorBlue" android:textSize="@dimen/BigTextSize" android:layout_marginTop="15dp"/> </LinearLayout>
6.创建一个class继承GirdView的适配器,我们需要重写GirdView适配器class
package com.example.lenovo.mydemoapp.myMoreOptions; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.example.lenovo.mydemoapp.R; import com.example.lenovo.mydemoapp.myDeviceList.DeivceListAdapter; import java.util.ArrayList; import java.util.List; /** * Created by lenovo on 2018/5/22. */ /* GridView的适配器class */ public class MoreOptionsGridViewAdapter extends BaseAdapter { //创建一个数据集合,将传入的数组转化成List集合 private List<DataList> mdataLists = new ArrayList<DataList>(); //将传入的Context设置为全局变量 private Context mContext; public MoreOptionsGridViewAdapter(Context context){ super(); this.mContext = context; } @Override public int getCount() { return mdataLists.size(); } @Override public Object getItem(int position) { return mdataLists.get(position); } @Override public long getItemId(int position) { return position; } /* 自写一个数据导入的方法,在方法将在ListView的适配器class里调用, 因为我们将GridView适配器数据导入放到了ListView适配器class中 */ public void setmList(String[] name,int[] image){ for (int i=0;i<name.length;i++){ //实例化一个单例内部class导入数据 DataList dataList = new DataList(name[i],image[i]); //添加到集合中 mdataLists.add(dataList); } } /* 重写getView方法,获得控件单例,添加单例数据,缓存单例 */ @Override public View getView(int position, View convertView, ViewGroup parent) { //用于缓存的控件的class,目的是不让一个控件的获取需要反复使用findViewById,可以优化滚动布局速度 MoreOptionsViewHolder moreOptionsViewHolder; //如果当前的一个的View是空的,那就重新findViewById获取它。 if (convertView == null){ convertView = LayoutInflater.from(mContext).inflate(R.layout.more_options_grid_view_subclass,null); moreOptionsViewHolder = new MoreOptionsViewHolder(); moreOptionsViewHolder.name = (TextView)convertView.findViewById(R.id.more_options_grid_view_subclass_TextView); moreOptionsViewHolder.image = (ImageView)convertView.findViewById(R.id.more_options_grid_view_subclass_ImageView); convertView.setTag(moreOptionsViewHolder); }else { //如果有这个View,那就继续使用已经找到的子类控件实例 moreOptionsViewHolder = (MoreOptionsViewHolder)convertView.getTag(); } //根据当前位置获取List数据集合中的单例 DataList dataList = mdataLists.get(position); //配置控件单例对应的List单例数据 moreOptionsViewHolder.image.setImageResource(dataList.getImage()); moreOptionsViewHolder.name.setText(dataList.getName()); return convertView; } /* 写一个数据存放的单例内部class */ class DataList{ private String name; private int image; public DataList(String name,int image){ this.name = name; this.image = image; } public int getImage() { return image; } public String getName() { return name; } } /* 控件缓存 */ class MoreOptionsViewHolder { public TextView name; public ImageView image; } }
7.创建ListView适配器使用的数据集合的单例class。
package com.example.lenovo.mydemoapp.myMoreOptions; import android.widget.GridView; /** * Created by lenovo on 2018/5/23. */ public class MoreOptionsDataLineViewData { private GridView gridView; private String TitleName ; public MoreOptionsDataLineViewData(String titleName,GridView gridView){ this.TitleName = titleName; this.gridView = gridView; } public String getTitleName() { return TitleName; } public GridView getGridView() { return gridView; } }
8.创建一个class继承ListView的适配器,我们需要重写ListView适配器class
package com.example.lenovo.mydemoapp.myMoreOptions; import android.content.Context; import android.support.annotation.LayoutRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.TextView; import com.example.lenovo.mydemoapp.R; import java.util.ArrayList; import java.util.List; /** * Created by lenovo on 2018/5/23. */ /* ListView的适配器类 */ public class MoreOptionsListViewAdapter extends ArrayAdapter<MoreOptionsDataLineViewData>{ List<MoreOptionsDataLineViewData> mlineViewDatas; //布局ID int resourceId; public MoreOptionsListViewAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<MoreOptionsDataLineViewData> objects) { super(context, resource, objects); resourceId = resource; } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { MoreOptionsDataLineViewData moreOptionsDataLineViewData = getItem(position); View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false); TextView textView = (TextView)view.findViewById(R.id.MoreOptions_GridView_TitleName); GridView gridView = (GridView)view.findViewById(R.id.MoreOptions_GridView); //导入标题栏数据 textView.setText(moreOptionsDataLineViewData.getTitleName()); //实例化一个GridView的适配器class MoreOptionsGridViewAdapter moreOptionsGridViewAdapter = new MoreOptionsGridViewAdapter(view.getContext()); //添加适配器的数据 moreOptionsGridViewAdapter.setmList(new MoreOptionsData().getContent_Text_Attrs()[position] ,new MoreOptionsData().getContent_Image_Attrs()[position]); //将gridView设置适配器 gridView.setAdapter(moreOptionsGridViewAdapter); return view; } }
9.在主activity里实例ListView,处理数据,数据导入适配器,ListView设置适配器
package com.example.lenovo.mydemoapp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.GridView; import android.widget.ListView; import com.example.lenovo.mydemoapp.myMoreOptions.MoreOptionsData; import com.example.lenovo.mydemoapp.myMoreOptions.MoreOptionsDataLineViewData; import com.example.lenovo.mydemoapp.myMoreOptions.MoreOptionsGridViewAdapter; import com.example.lenovo.mydemoapp.myMoreOptions.MoreOptionsListViewAdapter; import java.util.ArrayList; import java.util.List; public class MoreOptions extends AppCompatActivity { //实例数据class private MoreOptionsData mMoreOptionsData = new MoreOptionsData(); //创建listView使用的数据集合 private List<MoreOptionsDataLineViewData> lineViewDatas = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_more_options); ListView listView = (ListView)findViewById(R.id.MoreOptions_ListView); //根据标题名称数组长度创建GridView的数量 for (int i=0;i<mMoreOptionsData.getTitle_Text_Attrs().length;i++){ //创建GridView的实例,注意这里的GridView我们并没有设置适配器,而是直接添加到List数据集合中,一起传入ListView的适配器Class里面。 //我们将在ListView的适配器class里面,在给GridView的单例设置GridView的适配器class GridView gridView = (GridView)findViewById(R.id.MoreOptions_GridView); //给集合的单例添加数据: 数据为一个标题名称,一个GridView实例 MoreOptionsDataLineViewData lineViewData = new MoreOptionsDataLineViewData(mMoreOptionsData.getTitle_Text_Attrs()[i],gridView); ///将单例数据导入listView使用的数据集合中 lineViewDatas.add(lineViewData); } //给ListView的适配器导入数据 MoreOptionsListViewAdapter moreOptionsListViewAdapter = new MoreOptionsListViewAdapter(MoreOptions.this,R.layout.more_options_grid_view,lineViewDatas); //给ListView设置适配器 listView.setAdapter(moreOptionsListViewAdapter); } }