- 浏览: 91305 次
- 性别:
- 来自: 长沙
文章分类
最新评论
-
wangyudong:
家里是拨号上网,不行的,找到了一个Holer工具,只需要配置一 ...
【如何通过广域网访问局域网的服务器?】 -
叮咚可乐名:
大数据就是这么任性第一季数据结构和算法http://pan.b ...
数据结构与算法-简介 -
戢_时光:
...
【Java集合之二】Set集合 -
lzg406:
HTTP默认方式下,使用持久连接。 这个值得推敲
【应用层】之一:HTTP协议与FTP协议 -
mute_:
特别腻害呢
正则表达式1:概念
本文围绕以下三个部分展开:
一、BaseAdapter 自定义适配器
二、一个案例
附 代码补充
一、BaseAdapter 自定义适配器
它是 Android 应用程序中经常用到的基础适配器,它的主要用途是将一组数据传到 ListView、Spinner、Gallery 及 GridView 等 UI 显示组件。
二、一个案例
案例说明:
读取手机的SD卡中的目录和文件(全部读出/过滤不允许读的文件和隐藏文件),并显示成上图的样子。
目录:显示出目录(文件夹)的图标、目录名、包含几个文件。文件:显示出文件的图标、文件名、文件大小。
点击右边的按钮,出现弹出菜单,里面有“复制”和“删除”两项。分别点击,会弹出提示信息。
1. 在 styles.xml(v21) 中设置标题栏颜色。
2. 在功能清单中授予读取SD卡的权限,这样,本APP才可以读取到手机SD卡。
3. 启动后,会先启动MainAcitivity,然后加载主活动的布局文件(主界面)。
因此要写主界面 activity_main.xml :列表框(ListView)。
因为ListView里面也有布局文件,用来放图片、文件/目录名等控件,因此接下来写里面的布局文件。该布局文件中,有一些字符串,因此先在 strings.xml 中写需要的字符串。
然后再创建里面的布局文件:file_item.xml ,然后写布局。
4. 判断SD卡状态,并读取SD卡内容。
(1)判断SD卡状态是否有效。如果有效,弹出提示“SD card is ok”;否则,弹出提示:“读取SD卡出错”。
然后在手机上部署,显示以下效果,说明SD卡正在使用。
(2)获得SD卡的根目录下的目录/文件列表。(此处获得的,是所有的目录和文件列表)
(3)先初始化根路径,然后通过创建文件过滤器,过滤不允许读的文件和隐藏文件,接着获得SD卡根目录下面允许读的文件/目录列表。
其中,用到了SD卡文件过滤器 SdFileFilter ,因此需创建此文件过滤器。
注意:以上只是获得了文件/目录列表,并放入了数组中,但并未进行填充。
5. 创建文件适配器 FileAdapter 类,继承自 BaseAdapter。然后将数据与该适配器关联,接着将布局与适配器关联。
6. 进入 FileAdapter 类,写该文件适配器。
(1)创建构造方法。
(2)继承了 BaseAdapter 类,要重写(override)四个方法。
(2.1)重写 getCount() 方法。
(2.2)重写 getItem(int position) 方法。
(2.3)重写 getItemId(int position) 方法。
(2.4)重写 getView(int position, View convertView, ViewGroup parent) 方法。
注:上面在填充的时候,需要填充 “文件大小:%,d 字节”和“目录: %d 个字节”,因此把这两个字符串也写进 strings.xml 中。
(2.4.1)列表项的【结构持有者】:ViewHolder 。
(2.4.2)自定义的 ImageButton 点击监听器:ImageButtonListener 。
注:在 ImageButtonListener 中,这儿实现的是,在点击“复制”或“删除”后,弹出提示信息。也可以,通过调用 copyFile() 或者 deleteFile() 方法,然后通过流来实现文件/目录的复制和删除。
上面用到了弹出菜单 PopupMenu ,因此要创建弹出菜单: popup.xml。
附 代码补充
项目目录结构如下:
(1)styles.xml(v21)
(2)AndroidManifest.xml
(3)strings.xml
(4)activity_main.xml
(5)file_item.xml
(6)MainActivity
(7)SdFileFilter
(8)FileAdapter
(9)popup.xml
一、BaseAdapter 自定义适配器
二、一个案例
附 代码补充
一、BaseAdapter 自定义适配器
它是 Android 应用程序中经常用到的基础适配器,它的主要用途是将一组数据传到 ListView、Spinner、Gallery 及 GridView 等 UI 显示组件。
二、一个案例
案例说明:
读取手机的SD卡中的目录和文件(全部读出/过滤不允许读的文件和隐藏文件),并显示成上图的样子。
目录:显示出目录(文件夹)的图标、目录名、包含几个文件。文件:显示出文件的图标、文件名、文件大小。
点击右边的按钮,出现弹出菜单,里面有“复制”和“删除”两项。分别点击,会弹出提示信息。
1. 在 styles.xml(v21) 中设置标题栏颜色。
<item name="android:colorPrimaryDark">@android:color/holo_blue_dark</item> <item name="android:colorPrimary">@android:color/holo_blue_light</item> <item name="android:navigationBarColor">@android:color/transparent</item>
2. 在功能清单中授予读取SD卡的权限,这样,本APP才可以读取到手机SD卡。
<!-- 授予此App读取SD卡的权限 (注意大小写,不能写为:ANDROID.PERMISSION.READ_EXTERNAL_STORAGE)--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
3. 启动后,会先启动MainAcitivity,然后加载主活动的布局文件(主界面)。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 加载主活动的布局文件 setContentView(R.layout.activity_main); }
因此要写主界面 activity_main.xml :列表框(ListView)。
<!-- 主活动的布局文件:列表框--> <ListView android:id="@+id/listView" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
因为ListView里面也有布局文件,用来放图片、文件/目录名等控件,因此接下来写里面的布局文件。该布局文件中,有一些字符串,因此先在 strings.xml 中写需要的字符串。
<string name="filename">文件名</string> <string name="summary">文件/目录 概要信息</string> <string name="copy">复制</string> <string name="delete">删除</string> <string name="sd_card_error">读取SD卡出错</string>
然后再创建里面的布局文件:file_item.xml ,然后写布局。
<ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:src="@drawable/ic_file" android:contentDescription="@string/filename"/> <ImageButton android:id="@+id/btnOperator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:src="@drawable/ic_more_vert_grey600_16dp" style="@android:style/Widget.DeviceDefault.Button.Borderless.Small"/> <TextView android:id="@+id/tvFilename" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/imageView" android:layout_marginLeft="18dp" android:layout_toRightOf="@id/imageView" android:text="@string/filename" android:textSize="16sp"/> <TextView android:id="@+id/tvSummary" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/tvFilename" android:layout_alignParentBottom="true" android:layout_alignStart="@id/tvFilename" android:text="@string/summary" android:textSize="12sp"/>
4. 判断SD卡状态,并读取SD卡内容。
(1)判断SD卡状态是否有效。如果有效,弹出提示“SD card is ok”;否则,弹出提示:“读取SD卡出错”。
// 获得当前设备的SD卡的状态:Environment.getExternalStorageState() // SD卡正在使用:Environment.MEDIA_MOUNTED if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(this,"SD card is ok",Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, getString(R.string.sd_card_error), Toast.LENGTH_SHORT).show(); }
然后在手机上部署,显示以下效果,说明SD卡正在使用。
(2)获得SD卡的根目录下的目录/文件列表。(此处获得的,是所有的目录和文件列表)
public class MainActivity extends Activity { private ListView listView; private File[] files; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listView); // 获得当前设备的SD卡的状态:Environment.getExternalStorageState() // SD卡正在使用:Environment.MEDIA_MOUNTED if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(this,"SD card is ok",Toast.LENGTH_SHORT).show(); // 获得SD卡的根目录下的目录/文件 files = Environment.getExternalStorageDirectory().listFiles(); } else { Toast.makeText(this, getString(R.string.sd_card_error), Toast.LENGTH_SHORT).show(); } }
(3)先初始化根路径,然后通过创建文件过滤器,过滤不允许读的文件和隐藏文件,接着获得SD卡根目录下面允许读的文件/目录列表。
public class MainActivity extends Activity { private ListView listView; private File[] files; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listView); // 获得当前设备的SD卡的状态:Environment.getExternalStorageState() // SD卡正在使用:Environment.MEDIA_MOUNTED if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // 初始化根路径(/storage/emulated/0) File sdPath = Environment.getExternalStorageDirectory(); // 创建文件过滤器(过滤不允许读的文件/隐藏文件) SdFileFilter sdFileFilter = new SdFileFilter(); // 获得SD卡的根目录下的目录/文件(文件列表) files = sdPath.listFiles(sdFileFilter); } else { Toast.makeText(this, getString(R.string.sd_card_error), Toast.LENGTH_SHORT).show(); } }
其中,用到了SD卡文件过滤器 SdFileFilter ,因此需创建此文件过滤器。
package com.xiangdong.baseadapter; import java.io.File; import java.io.FileFilter; /** * SD Card文件过滤器 * Created by Xiangdong on 2015/6/4. */ public class SdFileFilter implements FileFilter { /** * 不允许读的文件/隐藏文件 不显示 */ @Override public boolean accept(File pathname) { if (pathname.isHidden() || !pathname.canRead()) { return false; } return true; } }
注意:以上只是获得了文件/目录列表,并放入了数组中,但并未进行填充。
5. 创建文件适配器 FileAdapter 类,继承自 BaseAdapter。然后将数据与该适配器关联,接着将布局与适配器关联。
public class MainActivity extends Activity { private ListView listView; private File[] files; private FileAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listView); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File sdPath = Environment.getExternalStorageDirectory(); SdFileFilter sdFileFilter = new SdFileFilter(); files = sdPath.listFiles(sdFileFilter); // 数据(文件列表)显示的方式:数据与适配器关联 adapter = new FileAdapter(this, files); // 布局与适配器关联 listView.setAdapter(adapter); } else { Toast.makeText(this, getString(R.string.sd_card_error), Toast.LENGTH_SHORT).show(); } }
6. 进入 FileAdapter 类,写该文件适配器。
(1)创建构造方法。
/** * 自定义文件适配器类 * Created by Xiangdong on 2015/6/4. */ public class FileAdapter extends BaseAdapter { // 上下文 private Context context; // 数据(文件列表) private File[] files; // 布局填充器(加载布局文件) private LayoutInflater inflater; /** * 4.1 构造方法 * * @param context 上下文 * @param files 数据(文件列表) */ public FileAdapter(Context context, File[] files) { this.context = context; this.files = files; inflater = LayoutInflater.from(context); } }
(2)继承了 BaseAdapter 类,要重写(override)四个方法。
(2.1)重写 getCount() 方法。
/** * 获得数据的总数 * * @return 文件列表的长度 */ @Override public int getCount() { return files.length; }
(2.2)重写 getItem(int position) 方法。
/** * 获得特定位置的数据 * * @param position 位置 * @return 特定位置的数据 */ @Override public Object getItem(int position) { return files[position]; }
(2.3)重写 getItemId(int position) 方法。
/** * 获得特定位置数据的 id (使用SQLite的场景) * * @param position 位置 * @return 特定位置数据的 id */ @Override public long getItemId(int position) { // 位置是列表项在 ListView 中的索引 // 在排序规则改变时,位置的数值会改变 // id 是数据的唯一标识,不会改变 return 0; }
(2.4)重写 getView(int position, View convertView, ViewGroup parent) 方法。
/** * (2.4) 获得特定位置加载了数据的视图(列表项) * * @param position 位置 * @param convertView 可重用的视图 * @param parent 父元素 * @return 列表项 */ @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; ImageButtonListener listener = null; if (convertView == null) { // 若无【可重用的视图】,才实例化 xml 文件创建视图 // inflate 方法执行的次数为屏幕上能显示的列表项的最大值 convertView = inflater.inflate(R.layout.file_item, parent, false); // 创建【结构持有者】,获得视图中的各个控件 holder = new ViewHolder(); holder.imageView = (ImageView) convertView.findViewById(R.id.imageView); holder.btnOperator = (ImageButton) convertView.findViewById(R.id.btnOperator); holder.tvFilename = (TextView) convertView.findViewById(R.id.tvFilename); holder.tvSummary = (TextView) convertView.findViewById(R.id.tvSummary); // 创建按钮的监听器 listener = new ImageButtonListener(); // 注册监听器 holder.btnOperator.setOnClickListener(listener); // 将监听器存储【绑定】到按钮中 holder.btnOperator.setTag(listener); // 将【结构持有者】存储到视图中 convertView.setTag(holder); } else { // 有【可重用的视图】,则从中取出它的【结构持有者】 holder = (ViewHolder) convertView.getTag(); // 获得按钮的监听器 listener = (ImageButtonListener) holder.btnOperator.getTag(); } // 在【结构持有者】中加载 position 位置的数据 // 获得的是根据位置取出的一个,返回的是一个文件 File file = files[position]; // 进行填充 holder.tvFilename.setText(file.getName()); holder.tvSummary.setText(file.isFile() ? String.format(context.getString(R.string.fileSize), file.length()) : String.format(context.getString(R.string.contents), file.listFiles().length)); holder.imageView.setImageResource(file.isFile() ? R.drawable.ic_file : R.drawable.ic_folder); // 修改监听器的监听的数据 listener.setData(file); // 返回视图 return convertView; }
注:上面在填充的时候,需要填充 “文件大小:%,d 字节”和“目录: %d 个字节”,因此把这两个字符串也写进 strings.xml 中。
<string name="fileSize">文件大小:%,d 字节</string> <string name="contents">目录: %d 个文件</string>
(2.4.1)列表项的【结构持有者】:ViewHolder 。
/** * (2.4.1)列表项的 结构持有者 * 存储 file_item.xml 文件中的控件结构 * 直接通过字段访问,为提高性能 */ private static class ViewHolder { ImageView imageView; ImageButton btnOperator; TextView tvFilename; TextView tvSummary; }
(2.4.2)自定义的 ImageButton 点击监听器:ImageButtonListener 。
/** * (2.4.2)FileAdapter 的内部类 * 自定义的 ImageButton 点击监听器 */ private class ImageButtonListener implements View.OnClickListener { // 点击时获得的数据(文件/目录) private File data; public void setData(File data) { this.data = data; } @Override public void onClick(View v) { // 创建弹出菜单 PopupMenu menu = new PopupMenu(context, v); // 加载菜单文件 menu.inflate(R.menu.popup); // 注册菜单选项事件 menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { String text = ""; switch (item.getItemId()) { case R.id.action_copy: // copyFile(); text = context.getString(R.string.copy); break; case R.id.action_delete: // deleteFile(); text = context.getString(R.string.delete); } text += ": " + data.getName(); Toast.makeText(context, text, Toast.LENGTH_SHORT).show(); return true; } }); // 显示菜单 menu.show(); } }
注:在 ImageButtonListener 中,这儿实现的是,在点击“复制”或“删除”后,弹出提示信息。也可以,通过调用 copyFile() 或者 deleteFile() 方法,然后通过流来实现文件/目录的复制和删除。
上面用到了弹出菜单 PopupMenu ,因此要创建弹出菜单: popup.xml。
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_copy" android:title="@string/copy"/> <item android:id="@+id/action_delete" android:title="@string/delete"/> </menu>
附 代码补充
项目目录结构如下:
(1)styles.xml(v21)
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="AppTheme" parent="android:Theme.Material.Light"> <item name="android:colorPrimaryDark">@android:color/holo_blue_dark</item> <item name="android:colorPrimary">@android:color/holo_blue_light</item> <item name="android:navigationBarColor">@android:color/transparent</item> </style> </resources>
(2)AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xiangdong.baseadapter" > <!--1. 授予此App读取SD卡的权限 (注意大小写,不能写为:ANDROID.PERMISSION.READ_EXTERNAL_STORAGE)--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
(3)strings.xml
<resources> <string name="app_name">BaseAdapter</string> <string name="action_settings">Settings</string> <string name="filename">文件名</string> <string name="summary">文件/目录 概要信息</string> <string name="copy">复制</string> <string name="delete">删除</string> <string name="sd_card_error">读取SD卡出错</string> <string name="fileSize">文件大小:%,d 字节</string> <string name="contents">目录: %d 个文件</string> </resources>
(4)activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <!-- 2.主活动的布局文件:列表框--> <ListView android:id="@+id/listView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
(5)file_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="72dp" android:padding="@dimen/activity_horizontal_margin" android:descendantFocusability="blocksDescendants"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:src="@drawable/ic_file" android:contentDescription="@string/filename"/> <ImageButton android:id="@+id/btnOperator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:src="@drawable/ic_more_vert_grey600_16dp" style="@android:style/Widget.DeviceDefault.Button.Borderless.Small"/> <TextView android:id="@+id/tvFilename" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/imageView" android:layout_marginLeft="18dp" android:layout_toRightOf="@id/imageView" android:text="@string/filename" android:textSize="16sp"/> <TextView android:id="@+id/tvSummary" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/tvFilename" android:layout_alignParentBottom="true" android:layout_alignStart="@id/tvFilename" android:text="@string/summary" android:textSize="12sp"/> </RelativeLayout>
(6)MainActivity
package com.xiangdong.baseadapter; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.ListView; import android.widget.Toast; import java.io.File; public class MainActivity extends Activity { private ListView listView; private File[] files; private FileAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 2.加载主活动的布局文件 setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listView); // 3.获得当前设备的SD卡的状态:Environment.getExternalStorageState() // SD卡正在使用:Environment.MEDIA_MOUNTED if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //Toast.makeText(this,"SD card is ok",Toast.LENGTH_SHORT).show(); // 获得SD卡的根目录下的目录/文件 //files = Environment.getExternalStorageDirectory().listFiles(); // 3.1 初始化根路径(/storage/emulated/0) File sdPath = Environment.getExternalStorageDirectory(); // 3.2 创建文件过滤器(过滤不允许读的文件/隐藏文件) SdFileFilter sdFileFilter = new SdFileFilter(); // 3.3获得SD卡的根目录下的目录/文件(文件列表) files = sdPath.listFiles(sdFileFilter); // 4.数据(文件列表)显示的方式:数据与适配器关联 adapter = new FileAdapter(this, files); // 布局与适配器关联 listView.setAdapter(adapter); } else { Toast.makeText(this, getString(R.string.sd_card_error), Toast.LENGTH_SHORT).show(); } } //------------------------------------------------------------------------------------------- @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
(7)SdFileFilter
package com.xiangdong.baseadapter; import java.io.File; import java.io.FileFilter; /** * SD Card文件过滤器 * Created by Xiangdong on 2015/6/4. */ public class SdFileFilter implements FileFilter { /** * 不允许读的文件/隐藏文件 不显示 */ @Override public boolean accept(File pathname) { if (pathname.isHidden() || !pathname.canRead()) { return false; } return true; } }
(8)FileAdapter
package com.xiangdong.baseadapter; import android.content.Context; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.PopupMenu; import android.widget.TextView; import android.widget.Toast; import java.io.File; /** * 自定义文件适配器类 * Created by Xiangdong on 2015/6/4. */ public class FileAdapter extends BaseAdapter { // 上下文 private Context context; // 数据(文件列表) private File[] files; // 布局填充器(加载布局文件) private LayoutInflater inflater; /** * 4.1 构造方法 * * @param context 上下文 * @param files 数据(文件列表) */ public FileAdapter(Context context, File[] files) { this.context = context; this.files = files; inflater = LayoutInflater.from(context); } /** * 4.2.1 获得数据的总数 * * @return 文件列表的长度 */ @Override public int getCount() { return files.length; } /** * 4.2.2 获得特定位置的数据 * * @param position 位置 * @return 特定位置的数据 */ @Override public Object getItem(int position) { return files[position]; } /** * 4.2.3 获得特定位置数据的 id (使用SQLite的场景) * * @param position 位置 * @return 特定位置数据的 id */ @Override public long getItemId(int position) { // 位置是列表项在 ListView 中的索引 // 在排序规则改变时,位置的数值会改变 // id 是数据的唯一标识,不会改变 return 0; } /** * 4.3 获得特定位置加载了数据的视图(列表项) * * @param position 位置 * @param convertView 可重用的视图 * @param parent 父元素 * @return 列表项 */ @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; ImageButtonListener listener = null; if (convertView == null) { // 若无【可重用的视图】,才实例化 xml 文件创建视图 // inflate 方法执行的次数为屏幕上能显示的列表项的最大值 convertView = inflater.inflate(R.layout.file_item, parent, false); // 创建【结构持有者】,获得视图中的各个控件的作用 holder = new ViewHolder(); holder.imageView = (ImageView) convertView.findViewById(R.id.imageView); holder.btnOperator = (ImageButton) convertView.findViewById(R.id.btnOperator); holder.tvFilename = (TextView) convertView.findViewById(R.id.tvFilename); holder.tvSummary = (TextView) convertView.findViewById(R.id.tvSummary); // 创建按钮的监听器 listener = new ImageButtonListener(); // 注册监听器 holder.btnOperator.setOnClickListener(listener); // 将监听器存储【绑定】到按钮中 holder.btnOperator.setTag(listener); // 将【结构持有者】存储到视图中 convertView.setTag(holder); } else { // 有【可重用的视图】,则从中取出它的【结构持有者】 holder = (ViewHolder) convertView.getTag(); // 获得按钮的监听器 listener = (ImageButtonListener) holder.btnOperator.getTag(); } // 在【结构持有者】中加载 position 位置的数据 File file = files[position]; holder.tvFilename.setText(file.getName()); holder.tvSummary.setText(file.isFile() ? String.format(context.getString(R.string.fileSize), file.length()) : String.format(context.getString(R.string.contents), file.listFiles().length)); holder.imageView.setImageResource(file.isFile() ? R.drawable.ic_file : R.drawable.ic_folder); // 修改监听器的监听的数据 listener.setData(file); // 返回视图 return convertView; } /** * 4.3.1 列表项的 结构持有者 * 存储 file_item.xml 文件中的控件结构 * 直接通过字段访问,为提高性能 */ private static class ViewHolder { ImageView imageView; ImageButton btnOperator; TextView tvFilename; TextView tvSummary; } /** * 4.3.2 FileAdapter 的内部类 * 自定义的 ImageButton 点击监听器 */ private class ImageButtonListener implements View.OnClickListener { // 点击时获得的数据(文件/目录) private File data; public void setData(File data) { this.data = data; } @Override public void onClick(View v) { // 创建弹出菜单 PopupMenu menu = new PopupMenu(context, v); // 加载菜单文件 menu.inflate(R.menu.popup); // 注册菜单选项事件 menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { String text = ""; switch (item.getItemId()) { case R.id.action_copy: // copyFile(); text = context.getString(R.string.copy); break; case R.id.action_delete: // deleteFile(); text = context.getString(R.string.delete); } text += ": " + data.getName(); Toast.makeText(context, text, Toast.LENGTH_SHORT).show(); return true; } }); // 显示菜单 menu.show(); } } }
(9)popup.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/action_copy" android:title="@string/copy"/> <item android:id="@+id/action_delete" android:title="@string/delete"/> </menu>
发表评论
-
【攻克Android (43)】WebView (网络视图)
2015-09-09 22:15 1253本文围绕以下两个部分展开: 一、WebView WebVi ... -
WebView (网络视图)
2015-09-09 22:12 0本文围绕以下两个部分展开: 一、WebView WebVi ... -
【攻克Android (41)】HttpURLConnection
2015-09-08 17:43 1363本文围绕以下三个部分展开: 一、HttpURLConnec ... -
HttpURLConnection
2015-09-08 17:42 0本文围绕以下三个部分展开: 一、HttpURLConnec ... -
【攻克Android (40)】JSON解析
2015-09-07 20:49 1274本文围绕以下三个部分 ... -
JSON解析
2015-09-07 20:47 0本文围绕以下三个部分 ... -
【攻克Android (39):XML解析之四】Simple方式解析XML
2015-08-27 18:38 1750本文围绕以下三个部分 ... -
【攻克Android (38):XML解析之三】Pull方式解析XML
2015-08-27 09:25 1738本文围绕以下两个部分展开: 一、Pull解析 案例一:P ... -
【攻克Android (37):XML解析之二】SAX方式解析XML
2015-08-26 15:15 876本文围绕以下两个部分展开: 一、SAX解析 案例一 ... -
【XML解析之一】SAX方式解析XML
2015-08-26 02:58 0本文围绕以下四个部分展开: 一、SAX解析 案例一 ... -
【攻克Android (36):XML解析之一】DOM方式解析XML
2015-08-26 00:27 947本文围绕以下三个部分展开: 一、XML概述 二、DOM解析 ... -
DOM方式解析XML案例
2015-08-26 00:26 0本文围绕以下四个部分展开: 一、DOM解析 案例一 ... -
【XML解析之四】Simple方式解析XML
2015-08-27 18:36 0本文围绕以下三个部分 ... -
【XML解析之一】Pull方式解析XML
2015-08-26 02:56 0本文围绕以下四个部分展开: 一、Pull解析 案例一:P ... -
【攻克Android (22)】View/Tween Animation 视图动画(补间动画)
2015-08-25 21:22 885本文围绕以下四个部分 ... -
【攻克Android (22)】View/Tween Animation 视图动画(补间动画)
2015-08-25 21:21 0本文围绕以下四个部分 ... -
【攻克Android (45)】四大组件之 ContentProvider
2015-08-18 16:24 1118本文围绕以下两个部分展开: 一、ContentProvide ... -
【攻克Android (32)】Notification 通知
2015-08-17 19:57 952本文围绕以下两个部分展开: 一、通知 案例一 一 ... -
Notification 通知
2015-08-17 19:56 0本文围绕以下两个部分展开: 一、通知 案例一 一 ... -
BroadcastReceiver完整版
2015-08-17 13:15 0本文围绕以下四个部分展开: 一、广播 案例一:系统广播(属于 ...
相关推荐
自定义适配器继承自BaseAdapter或其子类,并重写其中的关键方法,如`getCount()`(返回数据项的数量)、`getItem(int position)`(获取指定位置的数据项)、`getItemId(int position)`(返回数据项的ID)和`getView...
在Android开发中,自定义适配器(Adapter)是一个至关重要的概念,特别是在处理数据展示时。适配器是连接数据源和UI组件如ListView、GridView等的桥梁,它负责将数据转换为视图,以便在屏幕上显示。这篇博客...
在Android开发中,自定义适配器BaseAdapter是一种常见的技术,用于将数据绑定到各种视图组件,如ListView、GridView或Spinner等。BaseAdapter是Android SDK提供的一种抽象类,它是Adapter接口的一个实现,允许开发者...
1. 创建一个继承自BaseAdapter的类:BaseAdapter是所有自定义适配器的基础,它提供了getCount()、getItem()、getItemId()和getView()四个核心方法。getCount()返回数据集的大小,getItem()和getItemId()分别获取指定...
在这种情况下,我们可以创建一个继承自`BaseAdapter`或者`CursorAdapter`的自定义适配器,以便更好地控制数据的呈现方式。 下面是一些关于自定义`AutoCompleteTextView`适配器的关键知识点: 1. **继承自...
本教程将深入讲解如何使用ListView,结合自定义适配器以及解决Out-Of-Memory(OOM)问题。 首先,`ListView`是一个可滚动的视图,它能够显示一行行的数据。它通过Adapter来获取数据并将其渲染为可视化的列表项。...
Android中基于BaseAdapter的适配器理解.pdf
2. **编写自定义适配器类**:继承自`BaseAdapter`或基于现有的适配器类(如`ArrayAdapter`),自定义适配器的核心在于重写`getView()`方法,在此方法中根据位置获取数据并填充到布局中。 在自定义适配器中,还可以...
创建自定义适配器通常需要继承`BaseAdapter`类,重写其中的四个关键方法: - `getCount()`:返回数据集的大小。 - `getItem(int position)`:返回指定位置的数据项。 - `getItemId(int position)`:返回数据项的...
为了使ListView显示的数据更加丰富多样,我们通常需要自定义适配器(Adapter)。本文将深入探讨如何创建和使用ListView的自定义适配器,以及它的工作原理。 首先,我们要理解适配器在ListView中的角色。适配器是...
适配器(Adapter)是Android系统中连接数据源和视图组件的关键桥梁,而BaseAdapter作为基础类,为我们提供了自定义适配器的基础框架。 1. **Spinner的基本概念** Spinner是一个轻量级的下拉选择器,可以用于让用户...
自定义适配器是Android开发中的一个重要概念,主要用于在ListView、GridView、RecyclerView等视图组件中展示数据。在Android应用开发中,我们经常需要将数据集合(如ArrayList)与UI组件进行绑定,以便用户可以浏览...
BaseAdapter是所有自定义适配器的基类,它提供了一个框架,让我们能够将自定义的数据集绑定到这些视图上。本文将深入探讨BaseAdapter的工作原理和如何利用它来实现自定义适配器。 **1. BaseAdapter简介** ...
自定义适配器通常继承自`BaseAdapter`或`ArrayAdapter`,根据需求覆盖以上提到的方法。在`getView()`方法中,开发者可以自由设计视图布局,如使用不同的视图类型,实现复杂的交互效果。此外,`convertView`参数允许...
BaseAdapter是Android开发中一种常用的适配器,它允许开发者将数据集与各种视图控件,特别是ListView、GridView等进行绑定。杨鸿洋大神的博客提供了关于BaseAdapter的详细示例,帮助开发者节省时间,更好地理解其...
其中,`BaseAdapter`是自定义适配器的基础类,它为ListView等控件提供了一种灵活的方式来显示数据。 #### 二、BaseAdapter的关键方法 `BaseAdapter`主要包含了四个抽象方法,这些方法是必须被重写的: 1. **`...
为了自定义ListView的显示,我们需要创建一个继承自BaseAdapter的自定义适配器。在自定义适配器中,我们需要重写`getCount()`、`getItem()`、`getItemId()`和`getView()`方法。 3. 设置ListView:在XML布局文件中...
Android之自定义实现BaseAdapter通用适配器三 Android之自定义实现BaseAdapter通用适配器第三篇是Android开发中一个非常重要的知识点,主要讲解了如何自定义实现BaseAdapter通用适配器。 BaseAdapter是Android中一...
**一、自定义适配器** 1. **适配器基础概念**:适配器是连接数据源和UI视图的桥梁,它负责将数据转化为ListView可以显示的视图。在Android中,我们通常会继承BaseAdapter或ArrayAdapter来自定义适配器。 2. **创建...