初学Android项目:开发电子市场<第五天>

前四天, 完成了整个页面的显示。今天,就只做了详情页面的显示。

有事情要去兰州市里一趟....

运行效果图:


通过运行效果图来看,我们观察到详情页面的布局是特别复杂的,因此我们必须具体分析详情页面。

这里我将详情页面分为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);
			
		}
		
	}
}


DetailActivity.java

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;
	}
}

activity_detail.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="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()));
	}
}

app_detail_info.xml

<?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>

AppDetailBottomHolder.java

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());
				}
			});
		}
	}
}

app_detail_bottom.xml

<?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>

代码不怎么多,这些代码写起来也简单,因为我们已经把思路理清了,再说前面已经把框架搭建好了,就没什么难的了。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上善若水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值