首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

Android native应用开发简明教程 (2) - 本地应用的原理

本地应用原理 从NativeActivity说起 本地App,本质上是一个Java App调用了一个JNI的库,而应用的逻辑通过native代码来实现。NativeActivity是继承自Activity的一个类,代码在:/frameworks/base/core/java/android/app/NativeActivity.java中: public class NativeActivity extends Activity implements SurfaceHolder.Callback2,InputQueue.Callback, OnGlobalLayoutListener{ ... 然后我们再看NativeActivity的onCreate方法: @Override protected void onCrea

优秀的个人博客,低调大师

Android开发技巧——BaseAdapter的另一种优雅封装

RecyclerView虽然因其灵活性、高效性等特点而备受好评,但也不是一定得用它把ListView给替代掉。在某些场景中,ListView还是相对更适合的。比如数据量不大,不频繁更新,并且需要简单地设置一下divider或header、footer的时候,相对于RecyclerView的繁琐,ListView在实现上则表现得更方便和简洁。 过去的封装 在使用ListView的过程中,为了复用ListView中的convertView以及优化getView()时的findViewById操作,我们通常会引入一个ViewHolder类,来持有itemView的子view。但是不便的是,我们需要为每一种显示不同数据的ListView都重写其BaseAdapter的getView(),于是就有了对其的一种封装: 创建一个通常的ViewHolder,里面用SparseArray<View>来缓存,如下: public class ViewHolder { private final View itemView; private SparseArray<View> mHolderViews; public ViewHolder(View view) { itemView = view; view.setTag(this); mHolderViews = new SparseArray<>(); } public void hold(int... resIds) { for (int id : resIds) { mHolderViews.put(id, itemView.findViewById(id)); } } public <V> V get(int id) { return (V) mHolderViews.get(id); } } 再通过重写BaseAdapter的getView方法,作如下封装: @Override public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null) { holder = createHolder(position, parent); convertView = holder.itemView; } else { holder = (ViewHolder) convertView.getTag(); } bindData(position, holder, getItem(position)); return convertView; } public abstract ViewHolder createHolder(int position, ViewGroup parent); public abstract void bindData(int position, ViewHolder holder, T data); 这样使用的时候只需要继承并实现两个抽象方法即可。 这样写法,在后来我觉得还是有些别扭的地方。一是使用的时候还是需要去继承我们封装过的Adapter;二是在bindData()方法中,需要对每一个我们要设置的控件调用holder.get(id)方法,才能开始赋值或进行其他的设置,当我们的item的控件较多时,这些调用会使bindData()显得臃肿而不够纯粹,于是我又对其进行了另一种封装。 另一种优雅封装 这里我主要是通过接口解决重写Adapter的问题,然后再借鉴RecyclerView.ViewHolder,封装结果如下: 假设我们重写BaseAdapter的类为BaseListAdapter,那么首先定义它的一个静态内部类: public static abstract class ViewHolder { public final View itemView; public ViewHolder(View itemView) { this.itemView = itemView; itemView.setTag(this); } } 然后我们定义一个接口,用于创建ViewHolder以及绑定数据,如下: package com.githang.android.snippet.demo.adapter.adapter; import android.view.ViewGroup; public interface ViewCreator<T, H extends BaseListAdapter.ViewHolder> { H createHolder(int position, ViewGroup parent); /** * 设置列表里的视图内容 * * @param position 在列表中的位置 * @param holder 该位置对应的视图 */ void bindData(int position, H holder, T data); } 这里定义了两个泛型 ,一个是T,表示我们Adapter里的数据对象,另一个是H,为我们的ViewHolder的子类,表示我们最终创建出来的ViewHolder。 接下来,修改我们的BaseListAdapter,如下: public class BaseListAdapter<T, H extends BaseListAdapter.ViewHolder> extends BaseAdapter { private final List<T> mData; private final ViewCreator<T, H> mViewCreator; public BaseListAdapter(ViewCreator<T, H > creator) { this(new ArrayList<T>(), creator); } public BaseListAdapter(List<T> data, ViewCreator<T, H> creator) { mData = data == null ? new ArrayList<T>() : data; mViewCreator = creator; } @Override public int getCount() { return mData.size(); } @Override public T getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { final H holder; if (convertView == null) { holder = mViewCreator.createHolder(position, parent); convertView = holder.itemView; } else { holder = (H) convertView.getTag(); } mViewCreator.bindData(position, holder, getItem(position)); return convertView; } public void update(List<T> data) { mData.clear(); addData(data); } public void addData(List<T> data) { if (data != null) { mData.addAll(data); } notifyDataSetChanged(); } public static abstract class ViewHolder { public final View itemView; public ViewHolder(View itemView) { this.itemView = itemView; itemView.setTag(this); } } } 在这个BaseListAdapter里,同样定义了两个泛型,与我们的ViewCreator相同。我们创建ViewHolder及绑定数据的操作,通过调用该接口来执行(见getView方法),而该接口实例则通过构造方法传入。 这样,我们在使用的时候就可以先像使用RecyclerView一样,定义一个实现我们ViewHolder的子类,然后使我们的Fragment或Activity实现这个ViewCreator接口就可以了。 最后,我们还可以继承ViewHolder,封装一个通用的ViewHolder,代码如下: public static class DefaultViewHolder extends ViewHolder { private SparseArray<View> mHolderViews; public DefaultViewHolder(View view) { super(view); mHolderViews = new SparseArray<>(); } public void hold(int... resIds) { for (int id : resIds) { mHolderViews.put(id, itemView.findViewById(id)); } } public <V> V get(int id) { return (V) mHolderViews.get(id); } } 接下来是使用示例: public class SampleFragment extends Fragment implements ViewCreator<User,SampleFragment.UserViewHolder> { private BaseListAdapter<User, UserViewHolder> mAdapter = new BaseListAdapter<User, UserViewHolder>(this); @Override public UserViewHolder createHolder(int position, ViewGroup parent) { return new UserViewHolder(LayoutInflater.from(getActivity()).inflate(R.layout.item_user, parent, false)); } @Override public void bindData(int position, UserViewHolder holder, User user) { holder.name.setText(user.name); holder.email.setText(user.email); } static class UserViewHolder extends BaseListAdapter.ViewHolder { public final TextView name; public final TextView email; public UserViewHolder(View itemView) { super(itemView); name = (TextView) itemView.findViewById(R.id.name); email = (TextView) itemView.findViewById(R.id.email); } } } 全部的封装代码加上注释等也不过一百来行,但是可以看到,在这样的封装下,我们的代码已经变得很清晰。 本文的代码见:http://download.csdn.net/detail/maosidiaoxian/9700700 更详细的封装及相关代码见我的开源项目:https://github.com/msdx/AndroidSnippet/tree/master/library/src/main/java/com/githang/android/snippet/adapter

优秀的个人博客,低调大师

ios开发错误之: Undefined symbols for architecture x86_64

错误如下: Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_RoutingHTTPServer", referenced from: 出现类似 Undefined symbols for architecture x86_64 错误,一般是缺少包的引用,请尝试xcode-->项目-->Build phases-->Link Binaray With Libraries-->选择“+”号-->在弹出的对话框中搜索缺少的包。引用即可。 注: 1.如果是第三方包,搜索不到的需要网上搜索并导入,或使用Pods管理 2.如果点击"+"导入后还有错误,请查看日志是否错误内容改变,有时导入的包也需要依赖其它包,这时要再按上面步骤继续查找缺少的包。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册