内容概要:
- GirdView(网格视图)显示本地数据
- GirdView属性简介
- 案例一:用GirdView展示文字
- 案例二:用GridView显示已安装应用
- GridView显示网络
- 用GridView加载网络图片(上)
- 用GridView加载网络图片(下)
一、GirdView(网格视图)显示本地数据
1.GirdView属性简介
在 Android 程序设计中 GridView 跟 ListView 都是比较常用的多控件布局,而 GridView 更是实现九宫图的首选!
GridView 的用法很多,主要凸显的是那种网格式布 局,既有横向也有纵向的数据显示。
2. GridView 的使用场景
GridView 是 android 开发中常用的一个控件,它通常和以下几块内容结合使用
- GridView 的九宫格效果
- GridView 的获取系统应用
- GridView 动态加载数据
- 扩展:GridView 的上拉加载下拉刷新
3. GridView 中常用的一些属性 相关属性解析:
- android:numColumns=”auto_fit” //GridView 的列数设置为自动
- android:columnWidth=”90dp " //每列的宽度,也就是 Item 的宽度
- android:stretchMode=”columnWidth"//缩放与列宽大小同步(每列单元格的宽度自适应,边距固定)
- android:stretchMode=”SpacingWidth"//(每列单元格的宽度固定,边距自适应)
- android:verticalSpacing=”10dp” //两行之间的边距
- android:horizontalSpacing=”10dp” //两列之间的边距
- android:cacheColorHint="#00000000" //去除拖动时默认的黑色背景
- android:listSelector="#00000000" //去除选中时的黄色底色
- android:scrollbars="none" //隐藏 GridView 的滚动条
- android:fadeScrollbars="true" //设置为 true 就可以实现滚动条的自动隐藏和显示
- android:fastScrollEnabled="true" //GridView 出现快速滚动的按钮(至少滚动4 页才会显示)
- android:fadingEdge="none" //GridView 衰落(褪去)边缘颜色为空,缺省值是vertical。(可以理解为上下边缘的提示色)
- android:fadingEdgeLength="10dip" //定义的衰落(褪去)边缘的长度
- android:stackFromBottom="true" //设置为 true 时,你做好的列表就会显示你列表的最下面
- android:transcriptMode="alwaysScroll" //当你动态添加数据时,列表将自动 往下滚动最新的条目可以自动滚动到可视范围内
- android:drawSelectorOnTop="false"//点击某条记录不放,颜色会在记录的后 面成为背景色,内容的文字可见(缺省为 false)
4.GridView 实现数据加载的步骤:
GridView 适合“网格式布局”的开发模式,即从每个条目的显示组件,到对其进行控 制的数据结构,最后通过 Activity 等进行使用。
- 1) 首先是 item 组件,即用于每项布局输出的 xml 文件。
- 2) 在 Activity 的布局中加载《GridView》控件,并设置一系列属性
- 3) 定义数据结构(容器),即用于持有单个 Item 的数据,可以是简单的 String,也可
- 以通过抽象 Items 所需字段组成一个类,抽象的原则是与 Item 中的组件对应。本
- 文中上图涉及多个字段,因此通过抽象组件形成 BBSTopicItem 类。
- 4) 列表适配器。决定每行 Item 中具体显示什么内容,以怎样的样式显示等,通常通过继承 ArrayAdapter、SimpleAdapter 等实现。本文定义 BaseAdapter
- 5) 定义数据源,并对数据源进行初始化
- 6) 将适配器设置给 GridView
二、案例
1.案例一:用GirdView展示文字
布局文件
<?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">
<GridView
android:id="@+id/girdview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"
android:columnWidth="90dp"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:gravity="center"
>
</GridView>
</LinearLayout>
每一个格子item布局
<?xml version="1.0" encoding="utf-8"?>
<!--必须以TextView开头-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:id="@+id/textView"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="#000000"
android:textSize="40sp"
android:text="text"
android:background="#ed2f52"
>
</TextView>
和ListView使用一样,只是样式不同
public class GridView_Text extends AppCompatActivity {
GridView girdView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.girdview_text);
girdView=findViewById(R.id.girdview);
//设置固定数据
List<String> datalist=new ArrayList<>();
for (int i = 0; i <9 ; i++) {
datalist.add("单元格"+(i+1));
}
//设置简单的数组适配器
ArrayAdapter<String> arrayAdapter=new ArrayAdapter<>(this,R.layout.item_view,datalist);
girdView.setAdapter(arrayAdapter);
}
}
2.案例二:用GridView显示已安装应用
获取系统已经安装的应用的方法:getAppInfo()
在方法里加上下面这句可以过滤掉系统自带应用
//过滤掉系统应用
if((packageInfo.applicationInfo.flags& ApplicationInfo.FLAG_SYSTEM)==0)
主界面GridView_app.java
public class GridView_app extends AppCompatActivity {
private GridView gridView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gridview_app);
gridView = findViewById(R.id.girdview);
gridView.setAdapter(new GridAdapter_app(this, getAppInfo()));
}
//获取系统应用app信息
public List<AppInfo> getAppInfo() {
List<AppInfo> AppInfolist = new ArrayList<>();
//使用包管理器
PackageManager packageManager = getPackageManager();
//返回一个包的信息PackageInfo
List<PackageInfo> installedPackages = packageManager.getInstalledPackages(0);
for (int i = 0; i < installedPackages.size(); i++) {
//拿到包里面的信息
PackageInfo packageInfo = installedPackages.get(i);
AppInfo appInfo = new AppInfo();
//获取包里面应用名给appInfo里的应用名称赋值
appInfo.setAppName(packageInfo.applicationInfo.loadLabel(packageManager).toString());
appInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(packageManager));
appInfo.setVersionCode(packageInfo.versionCode);
appInfo.setVersionName(packageInfo.versionName);
appInfo.setPackageName(packageInfo.packageName);
AppInfolist.add(appInfo);
//过滤掉系统应用
// if((packageInfo.applicationInfo.flags& ApplicationInfo.FLAG_SYSTEM)==0)
AppInfolist.add(appInfo);
}
return AppInfolist;
}
}
封装应用信息的实体类 AppInfo
/***
* 建一个实体类封装应用信息
*/
public class AppInfo {
//应用名称
private String appName;
//应用包名
private String packageName;
//版本名称
private String versionName;
//版本号
private int versionCode;
//应用图标
private Drawable appIcon;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public int getVersionCode() {
return versionCode;
}
public void setVersionCode(int versionCode) {
this.versionCode = versionCode;
}
public Drawable getAppIcon() {
return appIcon;
}
public void setAppIcon(Drawable appIcon) {
this.appIcon = appIcon;
}
}
设置数据适配器
public class GridAdapter_app extends BaseAdapter {
private Context context;
private List<AppInfo> appInfoList;
private ViewHolder viewHolder;
//构造函数 将数据传进来
public GridAdapter_app(Context context, List<AppInfo> appInfoList) {
this.context = context;
this.appInfoList = appInfoList;
}
@Override
public int getCount() {
return appInfoList.size();
}
@Override
public Object getItem(int position) {
return appInfoList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//优化GridView
if (convertView == null) {
viewHolder = new ViewHolder();
//convertView=View.inflate(context,R.layout.gridview_app,null);
//绑定item布局.上下两种方法都可以
convertView = LayoutInflater.from(context).inflate(R.layout.item_app_view, null);
viewHolder.iv_aapIcon = convertView.findViewById(R.id.app_icon);
viewHolder.tv_appName = convertView.findViewById(R.id.app_name);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//设置数据
AppInfo appInfo = appInfoList.get(position);
viewHolder.tv_appName.setText(appInfo.getAppName() + " " + appInfo.getVersionName());
viewHolder.iv_aapIcon.setImageDrawable(appInfo.getAppIcon());
return convertView;
}
public class ViewHolder {
TextView tv_appName;
ImageView iv_aapIcon;
}
}
在初始化时添加适配器
//传参设置适配器
gridView.setAdapter(new GridAdapter_app(this, getAppInfo()));
3.案例三:用GridView加载网络图片(上)
1.设置布局
2.设置适配器
3.获取数据,从网络上下载图片
- 网络连接下载(记得添加网络权限在AndroidMainfest.xml中)
- 放到异步任务AsyncyTask中执行下载操作
- 下载完成提示更新UI
适配器设置
public class GridAdapter_internet extends BaseAdapter {
private List<ImageInfo> imageInfoList;
private Context context;
private ViewHolder viewHolder;
public GridAdapter_internet(Context context, List<ImageInfo> imageInfos) {
this.context = context;
this.imageInfoList = imageInfos;
}
@Override
public int getCount() {
return imageInfoList.size();
}
@Override
public Object getItem(int position) {
return imageInfoList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//优化性能
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = View.inflate(context, R.layout.item_internet_view, null);
viewHolder.text = convertView.findViewById(R.id.app_name);
viewHolder.imageView = convertView.findViewById(R.id.app_icon);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
ImageInfo imageInfo = imageInfoList.get(position);
viewHolder.text.setText(imageInfo.getText());
if (imageInfo.getBitmap() == null)//如果图片还没加载来
{//就默认给它加载一张本地图
viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
} else
viewHolder.imageView.setImageBitmap(imageInfo.getBitmap());
return convertView;
}
public class ViewHolder {
public TextView text;
public ImageView imageView;
}
}
图片信息:
public class ImageInfo {
private String imagePath;
private Bitmap bitmap;
private String text;
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
主Activity
public class GridView_internet extends AppCompatActivity {
private List<String> imgList;
private List<ImageInfo> imageInfoList;
private GridAdapter_internet gridAdapter_internet;
private GridView gridView;
private ImageLoadTask imageLoadTask;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gridview_internet);
gridView = findViewById(R.id.girdview);
initData();
}
private void initData() {
imgList = new ArrayList<>();
imgList.add("http://img5.duitang.com/uploads/item/201406/26/20140626164837_dzKds.jpeg");
imgList.add("http://img2.imgtn.bdimg.com/it/u=3980629563,3881837630&fm=21&gp=0.jpg");
imgList.add("http://img5q.duitang.com/uploads/item/201505/08/20150508155052_XJaNW.jpeg");
imgList.add("http://img4.duitang.com/uploads/item/201407/02/20140702105736_FdN5P.jpeg");
imgList.add("http://img2.imgtn.bdimg.com/it/u=2866652161,3841912673&fm=21&gp=0.jpg");
imgList.add("http://img4.imgtn.bdimg.com/it/u=883757693,2063816225&fm=21&gp=0.jpg");
imgList.add("http://cdn.duitang.com/uploads/item/201309/26/20130926110955_QtUdX.jpeg");
imgList.add("http://zjimg.5054399.com/allimg/160815/14_160815161625_9.jpg");
imgList.add("http://i-7.vcimg.com/trim/09ce7067d2467c54cf05bbd271ee3ec8430415/trim.jpg");
imageInfoList = new ArrayList<ImageInfo>();
for (int i = 0; i < imgList.size(); i++) {
ImageInfo imageInfo = new ImageInfo();
imageInfo.setImagePath(imgList.get(i));
imageInfo.setText("图片" + (i + 1));
imageInfoList.add(imageInfo);
}
//设置适配器
gridAdapter_internet = new GridAdapter_internet(this, imageInfoList);
gridView.setAdapter(gridAdapter_internet);
//异步下载
imageLoadTask = new ImageLoadTask(this, gridAdapter_internet);
imageLoadTask.execute();
}
//在网络上下载图片返回Bitmap
public Bitmap getImagefornet(String path) {
try {
URL url = new URL(path);
//发起链接
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.setConnectTimeout(10000);//超时时间
httpURLConnection.connect();
//拿到的输入流读取
InputStream inputStream = httpURLConnection.getInputStream();
//转换成Bitmap
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
inputStream.close();
return bitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//异步任务下载操作
public class ImageLoadTask extends AsyncTask<String, Void, Void> {
Context context;
GridAdapter_internet gridAdapter_internet;
private ImageLoadTask(Context context, GridAdapter_internet gridAdapter_internet) {
this.gridAdapter_internet = gridAdapter_internet;
}
@Override
protected Void doInBackground(String... strings) {
for (int i = 0; i < gridAdapter_internet.getCount(); i++) {
//拿到图片对象
ImageInfo imageInfo = (ImageInfo) gridAdapter_internet.getItem(i);
Bitmap bitmap = getImagefornet(imageInfo.getImagePath());//调用下载图片的方法
imageInfo.setBitmap(bitmap);//将下载的图片放到控件上
publishProgress();//通知刷新UI
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
gridAdapter_internet.notifyDataSetChanged();
}
}
}
效果:
使用Google的的网络库Glide去加载图片
在build.gradle中dependencies
添加依赖包
implementation 'com.github.bumptech.glide:glide:3.7.0'
在Adapter中getView中添加,直接下载好图片
//with第一个参数上下文
// load第二个图片地址、
//placeholder第三个占位符(默认图片)
// centerCrop居中裁切显示
// 默认缓冲
//into到你要显示的组件上
Glide.with(context).load(imageInfo.getImagePath()).
placeholder(R.mipmap.ic_launcher).centerCrop().
into(viewHolder.imageView);
// if (imageInfo.getBitmap() == null)//如果图片还没加载来
// {//就默认给它加载一张本地图
// viewHolder.imageView.setImageResource(R.mipmap.ic_launcher);
// } else
// viewHolder.imageView.setImageBitmap(imageInfo.getBitmap());
然后主Activity中的AsyncTask都可以省略了(取代了AsyncTask的下载操作)
//设置适配器
gridAdapter_internet = new GridAdapter_internet(this, imageInfoList);
gridView.setAdapter(gridAdapter_internet);
速度更快,不用每次都重新下载,会自动缓存下来,所以下次打开就很快就有图片了