前四天, 完成了整个页面的显示。今天,就只做了详情页面的显示。
有事情要去兰州市里一趟....
运行效果图:
通过运行效果图来看,我们观察到详情页面的布局是特别复杂的,因此我们必须具体分析详情页面。
这里我将详情页面分为5个部分:信息区域,安全区域,截图区域,介绍区域,底部区域。
我们将这个5个部分的布局抽取出来,分工完成,然后依次添加到详情页面的布局之中。这5个子布局分别对应着相应的Holder.
因此,以后我们遇到这种复杂的布局的时候,可以拆分为几部分,分别完成。如果写在一个xml文件中,就会显得臃肿,不便于维护。
看代码:
HomeFragment.java
package com.example.fragment;
import java.util.List; import android.content.Intent; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import com.btt.ui.widget.LoadingPager.LoadResult; import com.example.DetailActivity; import com.example.adapter.MyBaseAdapter; import com.example.bean.AppInfo; import com.example.holder.BaseHolder; import com.example.holder.HomeHolder; import com.example.protocol.HomeProtocol; import com.example.utils.UIUtils; public class HomeFragment extends BaseFragment { private List<AppInfo> mDatas; @Override protected View createSuccessView() { ListView mListView = new ListView(UIUtils.getContext()); MyBaseAdapter adapter = new HomeAdapter(mDatas,mListView); mListView.setAdapter(adapter); return mListView; } @Override protected LoadResult load() { HomeProtocol protocol = new HomeProtocol(); mDatas = protocol.load(0); return check(mDatas); } private class HomeAdapter<T> extends MyBaseAdapter implements OnItemClickListener{ public HomeAdapter(List<T> mDatas, ListView mListView) { super(mDatas); mListView.setOnItemClickListener(this); } @Override public BaseHolder getHolder() { return new HomeHolder(); } @Override public List onLoadMore() { HomeProtocol protocol = new HomeProtocol(); return protocol.load(getDatas().size()); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent = new Intent(UIUtils.getContext(), DetailActivity.class); String packageName = mDatas.get(position).getPackageName(); intent.putExtra(DetailActivity.PACKAGENAME, packageName); startActivity(intent); } } }
package com.example; import android.content.Intent; import android.support.v7.app.ActionBar; import android.view.View; import android.widget.FrameLayout; import android.widget.HorizontalScrollView; import com.btt.ui.widget.LoadingPager; import com.btt.ui.widget.LoadingPager.LoadResult; import com.example.bean.AppInfo; import com.example.holder.AppDetailBottomHolder; import com.example.holder.AppDetailDesHolder; import com.example.holder.AppDetailInfoHolder; import com.example.holder.AppDetailSafeHolder; import com.example.holder.AppDetailScreenHolder; import com.example.protocol.DetailProtocol; import com.example.utils.StringUtils; import com.example.utils.UIUtils; public class DetailActivity extends BaseActivity { public static final String PACKAGENAME = "PACKAGENAME"; private AppInfo mAppInfo; private String mPackageName; private ActionBar mActionBar; //各区域布局及其holder private FrameLayout mInfoLayout, mSafeLayout, mDesLayout, mBottomLayout; private HorizontalScrollView mScreenLayout; private AppDetailInfoHolder mInfoHolder; private AppDetailSafeHolder mSafeHolder; private AppDetailScreenHolder mScreenHolder; private AppDetailDesHolder mDesHolder; private AppDetailBottomHolder mBottomHolder; @Override public void init() { Intent i = getIntent(); if (i != null) {//从意图中获取packageName用户从服务端获取数据 mPackageName = i.getStringExtra(PACKAGENAME); } } /** 初始化actionBar */ public void initActionBar() { mActionBar = getSupportActionBar(); } /** 初始化布局 */ public void initView() { LoadingPager mContentView = new LoadingPager(this) { @Override public LoadResult load() { return DetailActivity.this.load(); } @Override public View createSuccessView() { return DetailActivity.this.createSuccessView(); } }; setContentView(mContentView); mContentView.show(); } /** 加载数据 */ private LoadResult load() { DetailProtocol protocol = new DetailProtocol(); protocol.setPackageName(mPackageName); mAppInfo = protocol.load(0); if (mAppInfo == null || StringUtils.isEmpty(mAppInfo.getPackageName())) { return LoadResult.ERROR; } return LoadResult.SUCCESS; } /** 获取数据后的显示的View */ private View createSuccessView() { View view = UIUtils.inflate(R.layout.activity_detail); // 添加信息区域 mInfoLayout = (FrameLayout) view.findViewById(R.id.detail_info); mInfoHolder = new AppDetailInfoHolder(); mInfoHolder.setData(mAppInfo); mInfoLayout.addView(mInfoHolder.getRootView()); // 添加安全区域 mSafeLayout = (FrameLayout) view.findViewById(R.id.detail_safe); mSafeHolder = new AppDetailSafeHolder(); mSafeHolder.setData(mAppInfo); mSafeLayout.addView(mSafeHolder.getRootView()); // 截图区域 mScreenLayout = (HorizontalScrollView) view.findViewById(R.id.detail_screen); mScreenHolder = new AppDetailScreenHolder(); mScreenHolder.setData(mAppInfo); mScreenLayout.addView(mScreenHolder.getRootView()); // 介绍区域 mDesLayout = (FrameLayout) view.findViewById(R.id.detail_des); mDesHolder = new AppDetailDesHolder(); mDesHolder.setData(mAppInfo); mDesLayout.addView(mDesHolder.getRootView()); // 底部区域 mBottomLayout = (FrameLayout) view.findViewById(R.id.bottom_layout); mBottomHolder = new AppDetailBottomHolder(); mBottomHolder.setData(mAppInfo); mBottomLayout.addView(mBottomHolder.getRootView()); mBottomHolder.startObserver(); return view; } }
<?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="match_parent" > <FrameLayout android:id="@+id/bottom_layout" android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentBottom="true" android:background="@drawable/detail_bottom_bg" > </FrameLayout> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/bottom_layout" android:layout_marginBottom="5dp" android:fillViewport="true" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <FrameLayout android:id="@+id/detail_info" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="@drawable/list_item_bg_normal" /> <FrameLayout android:id="@+id/detail_safe" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/detail_info" android:background="@drawable/list_item_bg_normal" /> <HorizontalScrollView android:id="@+id/detail_screen" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/detail_safe" android:background="@color/detail_screen_bg" android:fillViewport="true" android:padding="5dp" android:scrollbars="none" /> <FrameLayout android:id="@+id/detail_des" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/detail_screen" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="@drawable/list_item_bg_normal" /> </RelativeLayout> </ScrollView> </RelativeLayout>
DetailProtocol.java
package com.example.protocol; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; import com.example.bean.AppInfo; import com.example.utils.LogUtils; import com.example.utils.StringUtils; public class DetailProtocol extends BaseProtocol<AppInfo> { private String mPackageName = ""; public void setPackageName(String packageName) { mPackageName = packageName; } @Override protected String getKey() { return "detail"; } @Override protected String getParames() { if (StringUtils.isEmpty(mPackageName)) { return super.getParames(); } else { return "&packageName=" + mPackageName; } } @Override protected AppInfo parseFromJson(String json) { try { JSONObject obj = new JSONObject(json); AppInfo info = new AppInfo(); info.setId(obj.getLong("id")); info.setName(obj.getString("name")); info.setPackageName(obj.getString("packageName")); info.setIconUrl(obj.getString("iconUrl")); info.setStars(Float.valueOf(obj.getString("stars"))); info.setDownloadNum(obj.getString("downloadNum")); info.setVersion(obj.getString("version")); info.setDate(obj.getString("date")); info.setSize(obj.getLong("size")); info.setDownloadUrl(obj.getString("downloadUrl")); info.setDes(obj.getString("des")); info.setAuthor(obj.getString("author")); JSONArray array = obj.getJSONArray("screen"); List<String> screens = new ArrayList<String>(); for (int i = 0; i < array.length(); i++) { String screen = array.getString(i); screens.add(screen); } info.setScreen(screens); array = obj.getJSONArray("safe"); List<String> safeUrlList = new ArrayList<String>(); List<String> safeDesUrlList = new ArrayList<String>(); List<String> safeDesList = new ArrayList<String>(); List<Integer> safeDesColorList = new ArrayList<Integer>(); for (int i = 0; i < array.length(); i++) { JSONObject object = array.getJSONObject(i); String safeUrl = object.getString("safeUrl"); String safeDesUrl = object.getString("safeDesUrl"); String safeDes = object.getString("safeDes"); Integer safeDesColor = object.getInt("safeDesColor"); safeUrlList.add(safeUrl); safeDesUrlList.add(safeDesUrl); safeDesList.add(safeDes); safeDesColorList.add(safeDesColor); } info.setSafeUrl(safeUrlList); info.setSafeDesUrl(safeDesUrlList); info.setSafeDes(safeDesList); info.setSafeDesColor(safeDesColorList); return info; } catch (Exception e) { LogUtils.e(e); return null; } } }AppDetailInfoHolder.java
package com.example.holder; import android.view.View; import android.widget.ImageView; import android.widget.RatingBar; import android.widget.TextView; import com.example.R; import com.example.bean.AppInfo; import com.example.image.ImageLoader; import com.example.utils.StringUtils; import com.example.utils.UIUtils; public class AppDetailInfoHolder extends BaseHolder<AppInfo> { private ImageView mIcon; private TextView mTitleTxt, mDownloadTxt, mViesionTxt, mDateTxt, mSizeTxt; private RatingBar mRating; @Override public View initView() { View view = UIUtils.inflate(R.layout.app_detail_info); mIcon = (ImageView) view.findViewById(R.id.item_icon); mRating = (RatingBar) view.findViewById(R.id.item_rating); mTitleTxt = (TextView) view.findViewById(R.id.item_title); mDownloadTxt = (TextView) view.findViewById(R.id.item_download); mViesionTxt = (TextView) view.findViewById(R.id.item_version); mDateTxt = (TextView) view.findViewById(R.id.item_date); mSizeTxt = (TextView) view.findViewById(R.id.item_size); return view; } @Override public void refershView() { AppInfo info = getData(); String url = info.getIconUrl(); mIcon.setTag(url); ImageLoader.load(mIcon, url); mRating.setRating(info.getStars()); mTitleTxt.setText(info.getName()); mDownloadTxt.setText(UIUtils.getString(R.string.app_detail_download) + info.getDownloadNum()); mViesionTxt.setText(UIUtils.getString(R.string.app_detail_version) + info.getVersion()); mDateTxt.setText(UIUtils.getString(R.string.app_detail_date) + info.getDate()); mSizeTxt.setText(UIUtils.getString(R.string.app_detail_size) + StringUtils.formatFileSize(info.getSize())); } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/item_info_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp"> <RelativeLayout android:id="@+id/item_top" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:src="@drawable/ic_default" android:id="@+id/item_icon" android:layout_width="48dp" android:layout_height="48dp" android:layout_centerVertical="true" android:layout_marginRight="8dp" android:scaleType="fitXY"/> <RelativeLayout android:id="@+id/item_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@id/item_icon"> <TextView android:id="@+id/item_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" android:textColor="#ff333333" android:textSize="16dp"/> <RatingBar android:id="@+id/item_rating" android:layout_width="wrap_content" android:layout_height="@dimen/list_item_rating_height" android:layout_below="@id/item_title" android:layout_marginTop="@dimen/app_detail_rating_margin" android:isIndicator="true" android:progressDrawable="@drawable/ratingbar_small" android:rating="2.5"/> </RelativeLayout> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/item_top" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:orientation="horizontal"> <TextView android:id="@+id/item_download" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:ellipsize="end" android:singleLine="true" android:textColor="#ff7a7a7a" android:textSize="12dp"/> <TextView android:id="@+id/item_version" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:ellipsize="end" android:singleLine="true" android:textColor="#ff7a7a7a" android:textSize="12dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:orientation="horizontal"> <TextView android:id="@+id/item_date" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:ellipsize="end" android:singleLine="true" android:textColor="#ff7a7a7a" android:textSize="12dp"/> <TextView android:id="@+id/item_size" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:ellipsize="end" android:singleLine="true" android:textColor="#ff7a7a7a" android:textSize="12dp"/> </LinearLayout> </LinearLayout> </RelativeLayout>AppDetailSafeHolder.java
package com.example.holder; import java.util.List; import android.graphics.Color; import android.view.View; import android.view.View.MeasureSpec; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import com.example.R; import com.example.bean.AppInfo; import com.example.image.ImageLoader; import com.example.utils.UIUtils; import com.nineoldandroids.animation.Animator; import com.nineoldandroids.animation.Animator.AnimatorListener; import com.nineoldandroids.animation.ValueAnimator; public class AppDetailSafeHolder extends BaseHolder<AppInfo> implements OnClickListener { private RelativeLayout mSafeLayout; private LinearLayout mContentLayout; private ImageView mArrow; private ImageView[] mIv; private ImageView[] mDesIv; private TextView[] mDesTv; private LinearLayout[] mLayout; @Override public View initView() { View view = UIUtils.inflate(R.layout.app_detail_safe); mSafeLayout = (RelativeLayout) view.findViewById(R.id.safe_layout); mContentLayout = (LinearLayout) view.findViewById(R.id.safe_content); //默认进来是关闭的 mContentLayout.getLayoutParams().height = 0; mArrow = (ImageView) view.findViewById(R.id.safe_arrow); mArrow.setTag(false); mSafeLayout.setOnClickListener(this); mIv = new ImageView[4]; mIv[0] = (ImageView) view.findViewById(R.id.iv_1); mIv[1] = (ImageView) view.findViewById(R.id.iv_2); mIv[2] = (ImageView) view.findViewById(R.id.iv_3); mIv[3] = (ImageView) view.findViewById(R.id.iv_4); mDesIv = new ImageView[4]; mDesIv[0] = (ImageView) view.findViewById(R.id.des_iv_1); mDesIv[1] = (ImageView) view.findViewById(R.id.des_iv_2); mDesIv[2] = (ImageView) view.findViewById(R.id.des_iv_3); mDesIv[3] = (ImageView) view.findViewById(R.id.des_iv_4); mDesTv = new TextView[4]; mDesTv[0] = (TextView) view.findViewById(R.id.des_tv_1); mDesTv[1] = (TextView) view.findViewById(R.id.des_tv_2); mDesTv[2] = (TextView) view.findViewById(R.id.des_tv_3); mDesTv[3] = (TextView) view.findViewById(R.id.des_tv_4); mLayout = new LinearLayout[4]; mLayout[0] = (LinearLayout) view.findViewById(R.id.des_layout_1); mLayout[1] = (LinearLayout) view.findViewById(R.id.des_layout_2); mLayout[2] = (LinearLayout) view.findViewById(R.id.des_layout_3); mLayout[3] = (LinearLayout) view.findViewById(R.id.des_layout_4); return view; } @Override public void refershView() { AppInfo info = getData(); //对应着官方。安全。无广告等的图片下载地址 List<String> safeUrl = info.getSafeUrl(); //小框框打勾的下载地址 List<String> safeDesUrl = info.getSafeDesUrl(); //小框框打勾后面的描述信息 List<String> safeDes = info.getSafeDes(); //描述的文字颜色,有广告的颜色比较醒目 List<Integer> safeDesColor = info.getSafeDesColor(); for (int i = 0; i < 4; i++) { if (i < safeUrl.size() && i < safeDesUrl.size() && i < safeDes.size() && i < safeDesColor.size()) { ImageLoader.load(mIv[i], safeUrl.get(i)); ImageLoader.load(mDesIv[i], safeDesUrl.get(i)); mDesTv[i].setText(safeDes.get(i)); int color; int colorType = safeDesColor.get(i); if (colorType >= 1 && colorType <= 3) { color = Color.rgb(255, 153, 0); } else if (colorType == 4) { color = Color.rgb(0, 177, 62); } else { color = Color.rgb(122, 122, 122); } mDesTv[i].setTextColor(color); mIv[i].setVisibility(View.VISIBLE); mLayout[i].setVisibility(View.VISIBLE); } else { mIv[i].setVisibility(View.GONE); mLayout[i].setVisibility(View.GONE); } } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.safe_layout: expand(); break; default: break; } } private void expand() { final LayoutParams params = mContentLayout.getLayoutParams(); int targetHeight; int height = mContentLayout.getMeasuredHeight(); boolean flag = (Boolean) mArrow.getTag(); if (flag) { mArrow.setTag(false); targetHeight = 0; } else { mArrow.setTag(true); targetHeight = measureContentHeight(); } mSafeLayout.setEnabled(false); ValueAnimator va = ValueAnimator.ofInt(height, targetHeight); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator va) { params.height = (Integer) va.getAnimatedValue(); mContentLayout.setLayoutParams(params); } }); va.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator arg0) { } @Override public void onAnimationRepeat(Animator arg0) { } @Override public void onAnimationEnd(Animator arg0) { boolean flag = (Boolean) mArrow.getTag(); mArrow.setImageResource(flag ? R.drawable.arrow_up : R.drawable.arrow_down); mSafeLayout.setEnabled(true); } @Override public void onAnimationCancel(Animator arg0) { } }); va.setDuration(300); va.start(); } private int measureContentHeight() { int width = mContentLayout.getMeasuredWidth(); mContentLayout.getLayoutParams().height = LayoutParams.WRAP_CONTENT; int widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); int heightMeasureSpec = MeasureSpec.makeMeasureSpec(1000, MeasureSpec.AT_MOST); mContentLayout.measure(widthMeasureSpec, heightMeasureSpec); return mContentLayout.getMeasuredHeight(); } }app_detail_safe.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/safe_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp"> <RelativeLayout android:id="@+id/safe_title_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical"> <LinearLayout android:id="@+id/safe_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="horizontal"> <ImageView android:id="@+id/iv_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerInside"/> <ImageView android:id="@+id/iv_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:scaleType="centerInside"/> <ImageView android:id="@+id/iv_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:scaleType="centerInside"/> <ImageView android:id="@+id/iv_4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:scaleType="centerInside"/> </LinearLayout> <ImageView android:id="@+id/safe_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:scaleType="centerInside" android:src="@drawable/arrow_down"/> </RelativeLayout> <LinearLayout android:id="@+id/safe_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/safe_title_layout" android:orientation="vertical"> <LinearLayout android:id="@+id/des_layout_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:gravity="center_vertical" android:orientation="horizontal"> <ImageView android:id="@+id/des_iv_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerInside"/> <TextView android:id="@+id/des_tv_1" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" android:textColor="#ff7a7a7a" android:textSize="12dp"/> </LinearLayout> <LinearLayout android:id="@+id/des_layout_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:gravity="center_vertical" android:orientation="horizontal"> <ImageView android:id="@+id/des_iv_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerInside"/> <TextView android:id="@+id/des_tv_2" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" android:textColor="#ff7a7a7a" android:textSize="12dp"/> </LinearLayout> <LinearLayout android:id="@+id/des_layout_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:gravity="center_vertical" android:orientation="horizontal"> <ImageView android:id="@+id/des_iv_3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerInside"/> <TextView android:id="@+id/des_tv_3" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" android:textColor="#ff7a7a7a" android:textSize="12dp"/> </LinearLayout> <LinearLayout android:id="@+id/des_layout_4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:gravity="center_vertical" android:orientation="horizontal"> <ImageView android:id="@+id/des_iv_4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerInside"/> <TextView android:id="@+id/des_tv_4" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" android:textColor="#ff7a7a7a" android:textSize="12dp"/> </LinearLayout> </LinearLayout> </RelativeLayout>AppDetailScreenHolder.java
package com.example.holder; import android.view.View; import android.widget.ImageView; import com.example.R; import com.example.bean.AppInfo; import com.example.image.ImageLoader; import com.example.utils.UIUtils; public class AppDetailScreenHolder extends BaseHolder<AppInfo> { private ImageView[] mIv; @Override public View initView() { View view = UIUtils.inflate(R.layout.app_detail_screen); mIv = new ImageView[5]; mIv[0] = (ImageView) view.findViewById(R.id.screen_1); mIv[1] = (ImageView) view.findViewById(R.id.screen_2); mIv[2] = (ImageView) view.findViewById(R.id.screen_3); mIv[3] = (ImageView) view.findViewById(R.id.screen_4); mIv[4] = (ImageView) view.findViewById(R.id.screen_5); return view; } @Override public void refershView() { AppInfo info = getData(); for (int i = 0; i < 5; i++) { if (i < info.getScreen().size()) { ImageLoader.load(mIv[i], info.getScreen().get(i)); mIv[i].setVisibility(View.VISIBLE); } else { mIv[i].setVisibility(View.GONE); } } } }app_detail_screen.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="wrap_content" > <ImageView android:id="@+id/screen_1" android:layout_width="90dp" android:layout_height="150dp" android:paddingRight="5dp" android:src="@drawable/ic_default" android:scaleType="fitXY" /> <ImageView android:id="@+id/screen_2" android:layout_width="90dp" android:layout_height="150dp" android:src="@drawable/ic_default" android:layout_toRightOf="@id/screen_1" android:paddingRight="5dp" android:scaleType="fitXY"/> <ImageView android:id="@+id/screen_3" android:layout_width="90dp" android:layout_height="150dp" android:layout_toRightOf="@id/screen_2" android:src="@drawable/ic_default" android:paddingRight="5dp" android:scaleType="fitXY" /> <ImageView android:id="@+id/screen_4" android:layout_width="90dp" android:layout_height="150dp" android:layout_toRightOf="@id/screen_3" android:paddingRight="5dp" android:src="@drawable/ic_default" android:scaleType="fitXY"/> <ImageView android:id="@+id/screen_5" android:layout_width="90dp" android:layout_height="150dp" android:src="@drawable/ic_default" android:layout_toRightOf="@id/screen_4" android:paddingRight="5dp" android:scaleType="fitXY" /> </RelativeLayout>AppDetailDesHolder.java
package com.example.holder; import android.util.TypedValue; import android.view.View; import android.view.View.MeasureSpec; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.view.ViewParent; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import com.example.R; import com.example.bean.AppInfo; import com.example.utils.UIUtils; import com.nineoldandroids.animation.Animator; import com.nineoldandroids.animation.Animator.AnimatorListener; import com.nineoldandroids.animation.ValueAnimator; public class AppDetailDesHolder extends BaseHolder<AppInfo> implements OnClickListener { private RelativeLayout mLayout; private TextView mContent, mAuthor; private ImageView mArrow; private ScrollView mScrollView; private boolean mIsInit = true; @Override public View initView() { View view = UIUtils.inflate(R.layout.app_detail_des); mContent = (TextView) view.findViewById(R.id.des_content); mAuthor = (TextView) view.findViewById(R.id.des_author); mLayout = (RelativeLayout) view.findViewById(R.id.des_layout); mLayout.setOnClickListener(this); mArrow = (ImageView) view.findViewById(R.id.des_arrow); mArrow.setTag(false); return view; } @Override public void refershView() { AppInfo info = getData(); mContent.setText(info.getDes()); mAuthor.setText(UIUtils.getString(R.string.app_detail_author) + info.getAuthor()); if (mIsInit) { mContent.getLayoutParams().height = measureShortHeight(); mIsInit = false; } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.des_layout: expand(); break; default: break; } } private void expand() { final LayoutParams params = mContent.getLayoutParams(); int shortHeight = measureShortHeight(); int longHeight = measureLongHeight(); ValueAnimator va; final boolean flag = (Boolean) mArrow.getTag(); if (flag) { mArrow.setTag(false); va = ValueAnimator.ofInt(longHeight, shortHeight); } else { mArrow.setTag(true); va = ValueAnimator.ofInt(shortHeight, longHeight); } mLayout.setEnabled(false); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator va) { params.height = (Integer) va.getAnimatedValue(); mContent.setLayoutParams(params); if (!flag) { if (mScrollView == null) { mScrollView = getScrollView(); } if (mScrollView != null) { mScrollView.scrollTo(0, mScrollView.getHeight()); } } } }); va.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator arg0) { } @Override public void onAnimationRepeat(Animator arg0) { } @Override public void onAnimationEnd(Animator arg0) { boolean flag = (Boolean) mArrow.getTag(); mArrow.setImageResource(flag ? R.drawable.arrow_up : R.drawable.arrow_down); mLayout.setEnabled(true); } @Override public void onAnimationCancel(Animator arg0) { } }); va.setDuration(300); va.start(); } private int measureShortHeight() { int width = mContent.getMeasuredWidth(); int widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); int heightMeasureSpec = MeasureSpec.makeMeasureSpec(2000, MeasureSpec.AT_MOST); TextView tv = getTextView(); tv.setLines(7); tv.setMaxLines(7); tv.measure(widthMeasureSpec, heightMeasureSpec); return tv.getMeasuredHeight(); } private int measureLongHeight() { int width = mContent.getMeasuredWidth(); int widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); int heightMeasureSpec = MeasureSpec.makeMeasureSpec(2000, MeasureSpec.AT_MOST); TextView tv = getTextView(); tv.measure(widthMeasureSpec, heightMeasureSpec); return tv.getMeasuredHeight(); } private TextView getTextView() { TextView tv = new TextView(UIUtils.getContext()); tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); tv.setText(getData().getDes()); return tv; } private ScrollView getScrollView() { ScrollView scroView = null; View currentView = mLayout; while (true) { ViewParent parent = currentView.getParent(); if (parent == null || !(parent instanceof View)) { break; } else if (parent instanceof ScrollView) { scroView = (ScrollView) parent; break; } else { currentView = (View) parent; } } return scroView; } }app_detail_des.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/des_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="8dp"> <TextView android:id="@+id/des_titile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" android:text="@string/app_detail_introduction" android:textColor="#3c3c3c" android:textSize="14dp"/> <TextView android:id="@+id/des_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/des_titile" android:layout_marginTop="5dp" android:textColor="#7a7a7a" android:textSize="14dp"/> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/des_content" android:layout_marginTop="5dp" android:gravity="center_vertical"> <TextView android:id="@+id/des_author" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:singleLine="true" android:textColor="#b3b3b3" android:textSize="14dp"/> <ImageView android:id="@+id/des_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:scaleType="centerInside" android:src="@drawable/arrow_down"/> </RelativeLayout> </RelativeLayout>
package com.example.holder; import android.graphics.Color; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.FrameLayout; import com.btt.ui.widget.ProgressHorizontal; import com.example.R; import com.example.bean.AppInfo; import com.example.bean.DownloadInfo; import com.example.manage.DownloadManager; import com.example.utils.UIUtils; public class AppDetailBottomHolder extends BaseHolder<AppInfo> implements OnClickListener, DownloadManager.DownloadObserver { private Button mBtnFavorites, mBtnShare, mBtnProgress; private FrameLayout mLayout; private ProgressHorizontal mProgeressView; private float mProgress; private DownloadManager mDownloadManager; private int mState; @Override public View initView() { View view = UIUtils.inflate(R.layout.app_detail_bottom); mBtnFavorites = (Button) view.findViewById(R.id.bottom_favorites); mBtnShare = (Button) view.findViewById(R.id.bottom_share); mBtnProgress = (Button) view.findViewById(R.id.progress_btn); mBtnFavorites.setOnClickListener(this); mBtnShare.setOnClickListener(this); mBtnProgress.setOnClickListener(this); mBtnFavorites.setText(R.string.bottom_favorites); mBtnShare.setText(R.string.bottom_share); mLayout = (FrameLayout) view.findViewById(R.id.progress_layout); mProgeressView = new ProgressHorizontal(UIUtils.getContext()); mProgeressView.setId(R.id.detail_progress); mProgeressView.setOnClickListener(this); mProgeressView.setProgressTextVisible(true); mProgeressView.setProgressTextColor(Color.WHITE); mProgeressView.setProgressTextSize(UIUtils.dip2px(18)); mProgeressView.setBackgroundResource(R.drawable.progress_bg); mProgeressView.setProgressResource(R.drawable.progress); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); mLayout.addView(mProgeressView, params); return view; } @Override public void setData(AppInfo data) { if (mDownloadManager == null) { mDownloadManager = DownloadManager.getInstance(); } DownloadInfo downloadInfo = mDownloadManager.getDownloadInfo(data.getId()); if (downloadInfo != null) { mState = downloadInfo.getDownloadState(); mProgress = downloadInfo.getProgress(); } else { mState = DownloadManager.STATE_NONE; mProgress = 0; } super.setData(data); } @Override public void refershView() { refreshState(mState, mProgress); } public void refreshState(int state, float progress) { mState = state; mProgress = progress; switch (mState) { case DownloadManager.STATE_NONE: mProgeressView.setVisibility(View.GONE); mBtnProgress.setVisibility(View.VISIBLE); mBtnProgress.setText(UIUtils.getString(R.string.app_state_download)); break; case DownloadManager.STATE_PAUSED: mProgeressView.setVisibility(View.VISIBLE); mProgeressView.setProgress(progress); mProgeressView.setCenterText(UIUtils.getString(R.string.app_state_paused)); mBtnProgress.setVisibility(View.GONE); break; case DownloadManager.STATE_ERROR: mProgeressView.setVisibility(View.GONE); mBtnProgress.setVisibility(View.VISIBLE); mBtnProgress.setText(R.string.app_state_error); break; case DownloadManager.STATE_WAITING: mProgeressView.setVisibility(View.VISIBLE); mProgeressView.setProgress(progress); mProgeressView.setCenterText(UIUtils.getString(R.string.app_state_waiting)); mBtnProgress.setVisibility(View.GONE); break; case DownloadManager.STATE_DOWNLOADING: mProgeressView.setVisibility(View.VISIBLE); mProgeressView.setProgress(progress); mProgeressView.setCenterText(""); mBtnProgress.setVisibility(View.GONE); break; case DownloadManager.STATE_DOWNLOADED: mProgeressView.setVisibility(View.GONE); mBtnProgress.setVisibility(View.VISIBLE); mBtnProgress.setText(R.string.app_state_downloaded); break; default: break; } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bottom_favorites: UIUtils.showToastSafe(R.string.bottom_favorites); break; case R.id.bottom_share: UIUtils.showToastSafe(R.string.bottom_share); break; case R.id.progress_btn: case R.id.detail_progress: if (mState == DownloadManager.STATE_NONE || mState == DownloadManager.STATE_PAUSED || mState == DownloadManager.STATE_ERROR) { mDownloadManager.download(getData()); } else if (mState == DownloadManager.STATE_WAITING || mState == DownloadManager.STATE_DOWNLOADING) { mDownloadManager.pause(getData()); } else if (mState == DownloadManager.STATE_DOWNLOADED) { mDownloadManager.install(getData()); } break; default: break; } } public void startObserver() { mDownloadManager.registerObserver(this); } public void stopObserver() { mDownloadManager.unRegisterObserver(this); } @Override public void onDownloadStateChanged(DownloadInfo info) { refreshHolder(info); } @Override public void onDownloadProgressed(DownloadInfo info) { refreshHolder(info); } private void refreshHolder(final DownloadInfo info) { AppInfo appInfo = getData(); if (appInfo.getId() == info.getId()) { UIUtils.runInMainThread(new Runnable() { @Override public void run() { refreshState(info.getDownloadState(), info.getProgress()); } }); } } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/bottom_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/bottom_favorites" android:layout_width="68dp" android:layout_height="38dp" android:layout_alignParentLeft="true" android:layout_margin="6dp" android:background="@drawable/detail_btn" android:gravity="center" android:textColor="#ffffff" android:textSize="16dp" /> <Button android:id="@+id/bottom_share" android:layout_width="68dp" android:layout_height="38dp" android:layout_alignParentRight="true" android:layout_margin="6dp" android:background="@drawable/detail_btn" android:gravity="center" android:textColor="#ffffff" android:textSize="16dp" /> <FrameLayout android:id="@+id/progress_layout" android:layout_width="match_parent" android:layout_height="38dp" android:layout_centerVertical="true" android:layout_toLeftOf="@id/bottom_share" android:layout_toRightOf="@id/bottom_favorites" > </FrameLayout> <Button android:id="@+id/progress_btn" android:layout_width="match_parent" android:layout_height="38dp" android:layout_centerVertical="true" android:layout_toLeftOf="@id/bottom_share" android:layout_toRightOf="@id/bottom_favorites" android:background="@drawable/progress_btn" android:gravity="center" android:textColor="#ffffff" android:textSize="18dp" > </Button> </RelativeLayout>