cursorAdapter 取文件浏览器FileListCursorAdapter的例子
public class FileListCursorAdapter extends CursorAdapter { //将数据绑定到UI @Override public void bindView(View view, Context context, Cursor cursor) { FileInfo fileInfo = getFileItem(cursor.getPosition());//根据游标当前的指向,获取数据 //初始化UI @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return mFactory.inflate(R.layout.category_file_browser_item, parent, false); } //可以切换游标 @Override public void changeCursor(Cursor cursor) { mFileNameList.clear(); super.changeCursor(cursor); }
ArrayAdapter
在构造方法里面绑定数据源,然后在getView方法里面将数据绑定UI就好
ArrayAdapter(Context context, int resource) ArrayAdapter(Context context, int resource, int textViewResourceId) ArrayAdapter(Context context, int resource, T[] objects) ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects) ArrayAdapter(Context context, int resource, List<T> objects) ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects) // @Override public View getView(int position, View convertView, ViewGroup parent) {
expandableListView是可扩展子项的listView
但是这种空间只适用两层结构,用起来也比较麻烦,我个人感觉适用的范围比较窄。
要想做出类似于电脑上资源管理器的TreeView
应该的思路是
1.利用多叉树结构保存数据
2.使用listView,不同的层次有不同的pading,根据父子节点关系,控制层次开关。
class ProgressAdapter extends ArrayAdapter<FileInfo> { private int resourceId; public ProgressAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); resourceId = textViewResourceId; } @Override public View getView(int position, View convertView, ViewGroup parent) { Log.d(TAG, "position " + position + " " + convertView); if (convertView == null) { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(resourceId, null); } else { } FileInfo fileInfo = mSelectedFileList.get(position); VO vo = volist.get(fileInfo.filePath); if (vo == null) { vo = new VO(fileInfo); volist.put(vo.filePath, vo); Log.d(TAG, "position " + fileInfo); // progressTxt.put(vo.filePath, txt_progress); } ImageView img_progress_icon = (ImageView) convertView.findViewById(R.id.img_progress_icon); img_progress_icon.setImageResource(FileIconHelper.getFileIcon(Util.getExtFromFilename(vo.filePath))); TextView txt_progress_fileinfo = (TextView) convertView.findViewById(R.id.txt_progress_fileinfo); txt_progress_fileinfo.setText(mContext.getString(R.string.progress_fileinfo, vo.fileName, vo.fileSize / (1024 * 1024))); ProgressBar progress_bar = (ProgressBar) convertView.findViewById(R.id.progress_bar); progress_bar.setProgress(vo.progress); TextView txt_progress = (TextView) convertView.findViewById(R.id.txt_progress); txt_progress.setText(vo.progress + "%"); return convertView; } @Override public int getCount() { Log.d(TAG, "getCount ===== " + mSelectedFileList.size()); return mSelectedFileList.size(); } @Override public FileInfo getItem(int position) { return mSelectedFileList.get(position); } } //更新进度 public void updateProgress(String src, float f) { int value = f > 1 ? 100 : (int) (f * 100); Message message = new Message(); message.obj = src; message.what = 1; message.arg1 = value; mHandler.sendMessage(message); } Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 1) { VO vo = volist.get(msg.obj); vo.progress = msg.arg1; volist.remove(vo.filePath); volist.put(vo.filePath, vo); /* * ProgressBar progressBar = progresses.get(msg.obj); * progressBar.setProgress(msg.arg1); TextView textView = * progressTxt.get(msg.obj); textView.setText(msg.arg1 + "%"); * progressBar.postInvalidate(); textView.postInvalidate(); */ mAdapter.notifyDataSetChanged(); Log.d(TAG, " updateProgress " + msg.obj + " " + msg.arg1 + " " + vo.progress); } super.handleMessage(msg); } };
TreeView
//从根节点初始化朵叉树,要用到迭代 HashMap<String, DirTreeNode> map = new HashMap<String, DirTreeNode>(); private void initDirData() { map.clear(); rootNode = new DirTreeNode(ROOT_TREE_DIR, 0, null); map.put(ROOT_TREE_DIR, rootNode); PDFOutlineElement rootElement = new PDFOutlineElement(rootNode.mId + "", rootNode.mNodePath, false, true, null, rootNode.mLevel, true); // mPdfOutlinesCount.add(rootElement); // mPdfOutlines.add(rootElement); File[] listFiles = rootNode.mFile.listFiles(); initFiles(listFiles, rootNode); // Log.d(TAG, "alllllll " + Arrays.toString(map.keySet().toArray())); } private void initFiles(File[] listFiles, DirTreeNode fatherNode) { if (listFiles != null) { for (File f : listFiles) { synchronized (this) { if (f.isDirectory()) { DirTreeNode dt = null; if (!map.containsKey(f.getAbsolutePath())) { String absolutePath = f.getAbsolutePath(); dt = new DirTreeNode(absolutePath, map.size() + 1, fatherNode); String childPath = absolutePath.replace(ROOT_TREE_DIR, ""); int count = 0; for (int i = 0; i < childPath.length(); i++) { char c = childPath.charAt(i); if (c == File.separatorChar) { count++; } } // Log.d(TAG, childPath); dt.mLevel = count + 1; Log.d(TAG, " new DirNode ---- " + f.getAbsolutePath() + " level " + dt.mLevel + " id " + dt.mId); map.put(f.getAbsolutePath(), dt); PDFOutlineElement element = new PDFOutlineElement(dt.mId + "", dt.mNodePath, dt.mFatherNode != null, dt.mHasChild, dt.mFatherNode.mId + "", dt.mLevel, true); mPdfOutlinesCount.add(element); mPdfOutlines.add(element); Log.d(TAG, element + ""); if (f.listFiles() != null) { initFiles(f.listFiles(), dt); } } } } } } } class DirTreeNode { String mNodePath = null; DirTreeNode mFatherNode = null; private File mFile; int mId = 0; int mLevel = 0; boolean mHasChild = false; public DirTreeNode(String path, Integer id, DirTreeNode father) { mFatherNode = father; mNodePath = path; mFile = new File(path); if (father == null) { mLevel = 0; } else { mLevel = father.mLevel + 1; } mId = id; File[] listFiles = mFile.listFiles(); for (File f : listFiles) { if (f.isDirectory()) { mHasChild = true; break; } } } @Override public String toString() { return "DirTreeNode [mNodePath=" + mNodePath + ", mFatherNode=" + mFatherNode + ", mFile=" + mFile + ", mId=" + mId + ", mLevel=" + mLevel + ", mHasChild=" + mHasChild + "]"; } } class PDFOutlineElement implements Comparable { private String id; private String outlineTitle; private boolean mhasParent; private boolean mhasChild; private String parent; private int level; //适配器 private class TreeViewAdapter extends ArrayAdapter { public TreeViewAdapter(Context context, int textViewResourceId, List objects) { super(context, textViewResourceId, objects); mInflater = LayoutInflater.from(context); mfilelist = objects; mIconCollapse = BitmapFactory.decodeResource(context.getResources(), R.drawable.letou_manager_copy_collapse); mIconExpand = BitmapFactory.decodeResource(context.getResources(), R.drawable.letou_manager_copy_expand); } private LayoutInflater mInflater; private List<PDFOutlineElement> mfilelist; private Bitmap mIconCollapse; private Bitmap mIconExpand; public int getCount() { return mfilelist.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = mInflater.inflate(R.layout.outline, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); holder.icon = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } int level = mfilelist.get(position).getLevel(); holder.icon.setPadding(25 * (level > 0 ? (level - 1) : 0), holder.icon.getPaddingTop(), 0, holder.icon.getPaddingBottom()); String stringPath = mfilelist.get(position).getOutlineTitle(); boolean isRoot = stringPath.equalsIgnoreCase(ROOT_TREE_DIR); if (isRoot) { // convertView.setVisibility(View.GONE); // return convertView; } int lastIndexOf = stringPath.lastIndexOf(File.separatorChar); if (lastIndexOf != -1) { stringPath = stringPath.substring(lastIndexOf + 1); } holder.text.setText(isRoot ? ROOT_TREE_DIR : stringPath); if (mfilelist.get(position).isMhasChild() && (mfilelist.get(position).isExpanded() == false)) { holder.icon.setImageBitmap(mIconCollapse); holder.icon.setVisibility(View.VISIBLE); } else if (mfilelist.get(position).isMhasChild() && (mfilelist.get(position).isExpanded() == true)) { holder.icon.setImageBitmap(mIconExpand); holder.icon.setVisibility(View.VISIBLE); } else if (!mfilelist.get(position).isMhasChild()) { if (isRoot) { Log.d(TAG, " +++++++++++++++++"); } holder.icon.setImageBitmap(mIconCollapse); holder.icon.setVisibility(View.INVISIBLE); } holder.icon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!mPdfOutlinesCount.get(position).isMhasChild()) { Toast.makeText(mContext, mPdfOutlinesCount.get(position).getOutlineTitle(), 2000).show(); return; } Log.d(TAG, "" + mPdfOutlinesCount.get(position).isExpanded()); if (mPdfOutlinesCount.get(position).isExpanded()) { mPdfOutlinesCount.get(position).setExpanded(false); PDFOutlineElement pdfOutlineElement = mPdfOutlinesCount.get(position); ArrayList<PDFOutlineElement> temp = new ArrayList<PDFOutlineElement>(); for (int i = position + 1; i < mPdfOutlinesCount.size(); i++) { if (pdfOutlineElement.getLevel() >= mPdfOutlinesCount.get(i).getLevel()) { break; } temp.add(mPdfOutlinesCount.get(i)); } mPdfOutlinesCount.removeAll(temp); treeViewAdapter.notifyDataSetChanged(); } else { mPdfOutlinesCount.get(position).setExpanded(true); int level = mPdfOutlinesCount.get(position).getLevel(); int nextLevel = level + 1; Log.d(TAG, "nextLevel " + nextLevel); for (int i = 0; i < mPdfOutlines.size(); i++) { PDFOutlineElement pdfOutlineElement = mPdfOutlines.get(mPdfOutlines.size() - i - 1); int j = 1; if (pdfOutlineElement.getParent() == null) continue; if (mPdfOutlinesCount.get(position).getId().trim().equalsIgnoreCase(pdfOutlineElement.getParent().trim())) { Log.d(TAG, "pdfOutlineElement.getParent() " + pdfOutlineElement.getParent()); Log.d(TAG, "mPdfOutlinesCount.get(position).getId() " + mPdfOutlinesCount.get(position).getId()); pdfOutlineElement.setLevel(nextLevel); pdfOutlineElement.setExpanded(false); mPdfOutlinesCount.add(position + j, pdfOutlineElement); Log.d(TAG, position + " " + j + " " + pdfOutlineElement); j++; } } treeViewAdapter.notifyDataSetChanged(); } } }); final Integer id = Integer.valueOf(mPdfOutlinesCount.get(position).getId().trim()); if (whichDir != id) { convertView.setBackgroundColor(Color.BLACK); } convertView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "onClick" + id + " " + whichDir); if (whichDir != id) { whichDir = Integer.valueOf(mPdfOutlinesCount.get(position).getId().trim()); } Log.d(TAG, oldView + ""); if (oldView != null) { oldView.setBackgroundColor(Color.BLACK); } v.setBackgroundDrawable(drawableItemBg); oldView = v; mTargetDir = mPdfOutlinesCount.get(position).outlineTitle; updateDestPath(); } }); return convertView; } }
8. 已经发布了软件版本A,使用sqlite存储用户数据其DB version为1包含某张表T1,则其后需要发布版本B,在版本A的T1表结构的基础上又增加了2个新的字段,则能否在保存用户已经安装的版本A的数据的前提下,更新安装新版本B?
1,检测是否需要升级数据库文件。数据库文件版本是由versionCode控制。程序升级时,如果需要升级数据库,则要将versionCode+1。 2,将新数据库文件(存在于apk中),写入SD卡。 3,转移数据。 4,删除原数据库文件,重命名新数据库文件。 5,向新数据库写入当前数据库版本。
9. 你怎么看待在android上面应用MVC框架,是否有必要抽象独立于activity的C?
通过查看Android中的Launcher的源码,大家会发现其中会有LauncherModel.java,Workspace.java,Launcher.java。
其中LauncherModel为辅助文件封装了许多对数据库的操作(对应MVC中的Model);Workspace为一个抽象的桌面,将应用显示在用户面前,与用户进行交互(对应MVC中的View);Launcher是主要的Activity,里面有很多对用户的操作进行处理,并且将结果反馈在Workspace中(对应MVC中的Controller)。
1) 视图层(View):一般采用XML文件进行界面的描述,使用的时候可以非常方便的引入。当然,如何你对Android了解的比较的多了话,就一定可以想到在Android中也可以使用JavaScript+HTML等的方式作为View层,当然这里需要进行Java和JavaScript之间的通信,幸运的是,Android提供了它们之间非常方便的通信实现。
2) 控制层(Controller):Android的控制层的重任通常落在了众多的Acitvity的肩上,这句话也就暗含了不要在Acitivity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。
3) 模型层(Model):对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。就是应用程序中二进制的数据。