赞
踩
适配器(Adaper)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。
在上述电源接口这个示例中,5V电压就是Target接口,220v电压就是Adaptee类,而将电压从220V转换到5V就是Adapter。
//本来是220的电压,现在用户需求转成5v的电压 public void testAdapterMode2(){ ObjectAdapter adapter=new ObjectAdapter(new Volt220()); adapter.getVolt5(); }
public class ObjectAdapter implements FiveVolt { Volt220 mVolt220; public ObjectAdapter(Volt220 adaptee) { mVolt220 = adaptee; } public int getVolt220() { return mVolt220.getVolt220(); } @Override public int getVolt5() { return 0; } }
/** * Created by Administrator on 2017/9/15. * target角色 */ public interface FiveVolt { public int getVolt5(); }
/** * Created by Administrator on 2017/9/15. * Adaptee角色,需要被转换的对象 */ public class Volt220 { public int getVolt220() { return 220; } }
public class HottestAdapter extends BaseAdapter implements OnClickListener, DownloadManager.DownloadListener, ApkHelper.InstallListener, ApkHelper.UnInstallListener { String TAG="HottestAdapter"; private ArrayList<LaunNearbyHotBean> list; private LayoutInflater inflater; private Context mContext; private DownloadManager downloadManager; private String mDownloadSavePath; private ApkHelper apkHelper2; private ApkInstalledManager installedManager; // private ExpandableListView listView; public HottestAdapter(ArrayList<LaunRecommendGroup> groupDatas, Context mContext) { list = new ArrayList<LaunNearbyHotBean>(); for (LaunRecommendGroup group : groupDatas) { list.addAll(group.getApkList()); } this.mContext = mContext; inflater = LayoutInflater.from(mContext); downloadManager = DownloadManager.getInstance(mContext); mDownloadSavePath = HJStorageUtil.getDirDownload(mContext).getAbsolutePath() + "/"; apkHelper2 = ApkHelper.getInstance(mContext.getApplicationContext()); apkHelper2.registListener(this); apkHelper2.registUninstallListener(this); installedManager = ApkInstalledManager.getInstance(mContext.getApplicationContext()); EventBus.getDefault().register(this); mSwitchInstallPlungi=CXPolicyUtil.isShowUpdateSwitch(mContext, CXPolicyUtil.ON_HOTTEST_INSTALL_SWITCH); mSwitchInstallPlungi=!mSwitchInstallPlungi; if(PermissionUtilsO.isAndroidO()){ mSwitchInstallPlungi=false; } // if(CXConfig.DEBUG){ // mSwitchInstallPlungi=true; // } } public void destroy(){ EventBus.getDefault().unregister(this);} /**应用装容器还是装在系统 * false,装系统, * True,装容器 * * */ private boolean mSwitchInstallPlungi=false; @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = null; if (convertView == null) { viewHolder = new ViewHolder(); convertView = inflater.inflate(R.layout.launcher_recommend_item, null); viewHolder.ivAppIcon = (RoundImageView) convertView.findViewById(R.id.iv_appIc); viewHolder.tvAppName = (TextView) convertView.findViewById(R.id.tv_name); viewHolder.tvDownloadCount = (TextView) convertView.findViewById(R.id.tv_downNumber); viewHolder.tvDescription = (TextView) convertView.findViewById(R.id.tv_description); viewHolder.tvAppSize = (TextView) convertView.findViewById(R.id.tv_appSize); viewHolder.rlDownloadLayout = (RelativeLayout) convertView.findViewById(R.id.down_app); viewHolder.pbDownload = (ProgressBar) convertView.findViewById(R.id.child_right_progress_green); viewHolder.tvAppStatus = (TextView) convertView.findViewById(R.id.child_right_progress_txt); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } LaunNearbyHotBean apkModel = (LaunNearbyHotBean) getItem(position); apkModel.fromSource=5; viewHolder.position = position; viewHolder.key = apkModel.packageName; ImageLoaderUtil.loadAppIcon(viewHolder.ivAppIcon, apkModel.iconUrl); String showTitle=apkModel.title; if((Integer.valueOf(apkModel.serverApkOrg))>YYB_VALUE){ showTitle=YYB_FLAG+showTitle; } viewHolder.tvAppName.setText(showTitle); viewHolder.tvDownloadCount.setText(apkModel.getDownloadCount()); viewHolder.tvDescription.setText(apkModel.getAppDescription()); // if(apkModel.title.equals("天猫")){ // CXLog.e(TAG,"sizeFormat(apkModel.getSize()="+sizeFormat(apkModel.getSize())+"apkModel.getSize()=="+apkModel.getSize()); // } // // CXLog.e("FreeInstallAdapter", "model=====" + apkModel.title + // "packageName===" + apkModel.packageName+"apkModel.versionCode=="+apkModel.versionCode); // CXLog.e(TAG,"apkModelUrl=="+apkModel.downloadUrl); viewHolder.tvAppSize.setText(sizeFormat(apkModel.getSize())); setAppStatus(viewHolder, apkModel); viewHolder.rlDownloadLayout.setTag(viewHolder); viewHolder.rlDownloadLayout.setOnClickListener(this); return convertView; }
public class ListView extends AbsListView { /** * Used to indicate a no preference for a position type. */ static final int NO_POSITION = -1; /** * When arrow scrolling, ListView will never scroll more than this factor * times the height of the list. */ private static final float MAX_SCROLL_FACTOR = 0.33f; /** * When arrow scrolling, need a certain amount of pixels to preview next * items. This is usually the fading edge, but if that is small enough, * we want to make sure we preview at least this many pixels. */ private static final int MIN_SCROLL_PREVIEW_PIXELS = 2; /** * A class that represents a fixed view in a list, for example a header at the top * or a footer at the bottom. */ public class FixedViewInfo { /** The view to add to the list */ public View view; /** The data backing the view. This is returned from {@link ListAdapter#getItem(int)}. */ public Object data; /** <code>true</code> if the fixed view should be selectable in the list */ public boolean isSelectable; } private ArrayList<FixedViewInfo> mHeaderViewInfos = Lists.newArrayList(); private ArrayList<FixedViewInfo> mFooterViewInfos = Lists.newArrayList(); Drawable mDivider; int mDividerHeight; Drawable mOverScrollHeader; Drawable mOverScrollFooter; private boolean mIsCacheColorOpaque; private boolean mDividerIsOpaque; private boolean mHeaderDividersEnabled; private boolean mFooterDividersEnabled; private boolean mAreAllItemsSelectable = true; private boolean mItemsCanFocus = false; // used for temporary calculations. private final Rect mTempRect = new Rect(); private Paint mDividerPaint; // the single allocated result per list view; kinda cheesey but avoids // allocating these thingies too often. private final ArrowScrollFocusResult mArrowScrollFocusResult = new ArrowScrollFocusResult(); // Keeps focused children visible through resizes private FocusSelector mFocusSelector; public ListView(Context context) { this(context, null); } public ListView(Context context, AttributeSet attrs) { this(context, attrs, R.attr.listViewStyle); } public ListView(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); }
View obtainView(int position, boolean[] isScrap) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "obtainView"); isScrap[0] = false; // Check whether we have a transient state view. Attempt to re-bind the // data and discard the view if we fail. final View transientView = mRecycler.getTransientStateView(position); if (transientView != null) { final LayoutParams params = (LayoutParams) transientView.getLayoutParams(); // If the view type hasn't changed, attempt to re-bind the data. if (params.viewType == mAdapter.getItemViewType(position)) { final View updatedView = mAdapter.getView(position, transientView, this); // If we failed to re-bind the data, scrap the obtained view. if (updatedView != transientView) { setItemViewLayoutParams(updatedView, position); mRecycler.addScrapView(updatedView, position); } } isScrap[0] = true; // Finish the temporary detach started in addScrapView(). transientView.dispatchFinishTemporaryDetach(); return transientView; }
private View makeAndAddView(int position, int y, boolean flow, int childrenLeft, boolean selected) { View child; if (!mDataChanged) { // Try to use an existing view for this position child = mRecycler.getActiveView(position); if (child != null) { // Found it -- we're using an existing child // This just needs to be positioned setupChild(child, position, y, flow, childrenLeft, selected, true); return child; } } // Make a new view for this position, or convert an unused view if possible child = obtainView(position, mIsScrap); // This needs to be positioned and measured setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0]); return child; }
private View fillDown(int pos, int nextTop) { View selectedView = null; int end = (mBottom - mTop); if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { end -= mListPadding.bottom; } while (nextTop < end && pos < mItemCount) { // is this the selected item? boolean selected = pos == mSelectedPosition; View child = makeAndAddView(pos, nextTop, true, mListPadding.left, selected); nextTop = child.getBottom() + mDividerHeight; if (selected) { selectedView = child; } pos++; } setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1); return selectedView; }
@Override
protected void onAttachedToWindow() { super.onAttachedToWindow(); final ViewTreeObserver treeObserver = getViewTreeObserver(); treeObserver.addOnTouchModeChangeListener(this); if (mTextFilterEnabled && mPopup != null && !mGlobalLayoutListenerAddedFilter) { treeObserver.addOnGlobalLayoutListener(this); } if (mAdapter != null && mDataSetObserver == null) { mDataSetObserver = new AdapterDataSetObserver(); mAdapter.registerDataSetObserver(mDataSetObserver); // Data may have changed while we were detached. Refresh. mDataChanged = true; mOldItemCount = mItemCount; mItemCount = mAdapter.getCount(); } }
ListView覆写了AbsListView中的layoutChilden函数,在该函数中根据布局模式来布局Item View。Item View的个数、样式都通过Adapter对应的方法来获取,获取个数、Item View之后,将这些Item View布局到ListView对应的坐标上,再加上Item View的复用机制,整个ListView就基本运转起来了。
当然这里的Adapter并不是经典的适配器模式,但是却是对象适配器模式的优秀示例,也很好的体现了面向对象的一些基本原则。这里的Target角色和Adapter角色融合在一起,Adapter中的方法就是目标方法;而Adaptee角色就是ListView的数据集与Item View,Adapter代理数据集,从而获取到数据集的个数、元素。
通过增加Adapter一层来将Item View的操作抽象起来,ListView等集合视图通过Adapter对象获得Item的个数、数据元素、Item View等,从而达到适配各种数据、各种Item视图的效果。因为Item View和数据类型千变万化,Android的架构师们将这些变化的部分交给用户来处理,通过getCount、getItem、getView等几个方法抽象出来,也就是将Item View的构造过程交给用户来处理,灵活地运用了适配器模式,达到了无限适配、拥抱变化的目的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。