【0127】【项目实战】-【组件化封装思想实战Android App】-【10】课程详情页面开发
1.效果及思路
1.1 效果
【效果】在点击两次不同的页面之后,点击一次返回按钮就返回,返回的页面是首页;关键使用到的是activity的4种启动模式;

1.2 功能




2. 实现
2.1 布局及listView适配器数据的生成

【初始化数据】

【布局】

1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:background="@color/white" 5 > 6 7 <RelativeLayout 8 android:id="@+id/title_layout" 9 android:layout_width="match_parent" 10 android:layout_height="48dp" 11 > 12 13 <ImageView 14 android:id="@+id/back_view" 15 android:layout_width="25dp" 16 android:layout_height="25dp" 17 android:layout_centerVertical="true" 18 android:layout_marginLeft="10dp" 19 android:background="@drawable/comment_back_normal" 20 /> 21 22 <TextView 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:layout_centerInParent="true" 26 android:text="@string/course_detail" 27 android:textColor="@color/color_333333" 28 android:textSize="22sp" 29 /> 30 31 <View 32 android:layout_width="match_parent" 33 android:layout_height="0.5dp" 34 android:layout_alignParentBottom="true" 35 android:background="@color/color_999999" 36 /> 37 </RelativeLayout> 38 39 <ImageView 40 android:id="@+id/loading_view" 41 android:layout_width="match_parent" 42 android:layout_height="match_parent" 43 android:layout_below="@id/title_layout" 44 android:background="@color/white" 45 android:scaleType="center" 46 android:src="@drawable/loading_data_anim" 47 android:visibility="gone" 48 /> 49 50 <RelativeLayout 51 android:id="@+id/bottom_layout" 52 android:layout_width="match_parent" 53 android:layout_height="50dp" 54 android:layout_alignParentBottom="true" 55 android:visibility="gone" 56 > 57 58 <View 59 android:id="@+id/divider" 60 android:layout_width="match_parent" 61 android:layout_height="0.5dp" 62 android:background="@color/color_999999" 63 /> 64 65 <ImageView 66 android:id="@+id/jianpan_view" 67 android:layout_width="30dp" 68 android:layout_height="30dp" 69 android:layout_below="@id/divider" 70 android:layout_margin="6dp" 71 android:background="@drawable/icon_jianpan" 72 /> 73 74 <View 75 android:id="@+id/divider_2" 76 android:layout_width="0.5dp" 77 android:layout_height="match_parent" 78 android:layout_toRightOf="@id/jianpan_view" 79 android:background="@color/color_999999" 80 /> 81 82 <EditText 83 android:id="@+id/comment_edit_view" 84 android:layout_width="match_parent" 85 android:layout_height="match_parent" 86 android:layout_centerVertical="true" 87 android:layout_margin="8dp" 88 android:layout_toRightOf="@id/divider_2" 89 android:background="@null" 90 android:hint="@string/input_comment" 91 android:paddingLeft="10dp" 92 android:textColor="@color/color_333333" 93 android:textColorHint="@color/color_cccccc" 94 android:textSize="16sp"/> 95 96 <TextView 97 android:id="@+id/send_view" 98 android:layout_width="wrap_content" 99 android:layout_height="match_parent" 100 android:layout_alignParentRight="true" 101 android:layout_centerVertical="true" 102 android:layout_margin="8dp" 103 android:background="@color/color_ffff4444" 104 android:gravity="center" 105 android:paddingLeft="14dp" 106 android:paddingRight="14dp" 107 android:text="@string/send" 108 android:textColor="@color/white" 109 android:textSize="16sp" 110 /> 111 </RelativeLayout> 112 113 <ListView 114 android:id="@+id/comment_list_view" 115 android:layout_width="match_parent" 116 android:layout_height="match_parent" 117 android:layout_above="@id/bottom_layout" 118 android:layout_below="@+id/title_layout" 119 android:alwaysDrawnWithCache="false" 120 android:divider="@color/color_cccccc" 121 android:dividerHeight="0.5dp" 122 android:visibility="gone" 123 /> 124 </RelativeLayout>

【发出网络请求】


【接收网络传递回来的数据】


【更新UI】


【数据适配器】




【源码】
1 package com.youdu.adapter; 2 3 import android.content.Context; 4 import android.content.Intent; 5 import android.support.v4.view.ViewPager; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.view.View.OnClickListener; 9 import android.view.ViewGroup; 10 import android.widget.BaseAdapter; 11 import android.widget.ImageView; 12 import android.widget.LinearLayout; 13 import android.widget.RelativeLayout; 14 import android.widget.TextView; 15 16 import com.google.gson.Gson; 17 import com.youdu.R; 18 import com.youdu.activity.AdBrowserActivity; 19 import com.youdu.activity.PhotoViewActivity; 20 import com.youdu.core.AdContextInterface; 21 import com.youdu.core.video.VideoAdContext; 22 import com.youdu.module.recommand.RecommandBodyValue; 23 import com.youdu.share.ShareDialog; 24 import com.youdu.util.ImageLoaderManager; 25 import com.youdu.util.Util; 26 import com.youdu.adutil.Utils; 27 28 import java.util.ArrayList; 29 30 import cn.sharesdk.framework.Platform; 31 import de.hdodenhof.circleimageview.CircleImageView; 32 33 /** 34 * @author: qndroid 35 * @function: 36 * @date: 16/6/15 37 */ 38 public class CourseAdapter extends BaseAdapter { 39 /** 40 * 不同的item类型的标示 41 */ 42 private static final int CARD_COUNT = 4; 43 private static final int VIDOE_TYPE = 0x00; //视频类型的item 44 private static final int CARD_TYPE_ONE = 0x01; // 45 private static final int CARD_TYPE_TWO = 0x02; 46 private static final int CARD_TYPE_THREE = 0x03; 47 48 private LayoutInflater mInflate; //布局加载器; 49 private Context mContext; //上下文; 50 private ArrayList<RecommandBodyValue> mData; //需要加载的数据项; 51 private ViewHolder mViewHolder; 52 private VideoAdContext mAdsdkContext; 53 private ImageLoaderManager mImagerLoader; 54 55 public CourseAdapter(Context context, ArrayList<RecommandBodyValue> data) { 56 mContext = context; 57 mData = data; 58 mInflate = LayoutInflater.from(mContext); 59 mImagerLoader = ImageLoaderManager.getInstance(mContext); 60 } 61 62 @Override 63 public int getCount() { 64 return mData.size(); 65 } 66 67 @Override 68 public Object getItem(int position) { 69 return mData.get(position); 70 } 71 72 @Override 73 public long getItemId(int position) { 74 return position; 75 } 76 77 @Override 78 public int getViewTypeCount() { 79 return CARD_COUNT; 80 } 81 82 @Override 83 public int getItemViewType(int position) { 84 RecommandBodyValue value = (RecommandBodyValue) getItem(position); 85 return value.type; 86 } 87 88 89 @Override 90 public View getView(int position, View convertView, ViewGroup parent) { 91 int type = getItemViewType(position); 92 final RecommandBodyValue value = (RecommandBodyValue) getItem(position); 93 //无tag时 94 if (convertView == null) { 95 switch (type) { 96 case VIDOE_TYPE: 97 //显示video卡片 98 mViewHolder = new ViewHolder(); 99 convertView = mInflate.inflate(R.layout.item_video_layout, parent, false); 100 mViewHolder.mVieoContentLayout = (RelativeLayout) 101 convertView.findViewById(R.id.video_ad_layout); 102 mViewHolder.mLogoView = (CircleImageView) convertView.findViewById(R.id.item_logo_view); 103 mViewHolder.mTitleView = (TextView) convertView.findViewById(R.id.item_title_view); 104 mViewHolder.mInfoView = (TextView) convertView.findViewById(R.id.item_info_view); 105 mViewHolder.mFooterView = (TextView) convertView.findViewById(R.id.item_footer_view); 106 mViewHolder.mShareView = (ImageView) convertView.findViewById(R.id.item_share_view); 107 //为对应布局创建播放器 108 mAdsdkContext = new VideoAdContext(mViewHolder.mVieoContentLayout, 109 new Gson().toJson(value), null); 110 mAdsdkContext.setAdResultListener(new AdContextInterface() { 111 @Override 112 public void onAdSuccess() { 113 } 114 115 @Override 116 public void onAdFailed() { 117 } 118 119 @Override 120 public void onClickVideo(String url) { 121 Intent intent = new Intent(mContext, AdBrowserActivity.class); 122 intent.putExtra(AdBrowserActivity.KEY_URL, url); 123 mContext.startActivity(intent); 124 } 125 }); 126 break; 127 case CARD_TYPE_ONE: 128 mViewHolder = new ViewHolder(); 129 convertView = mInflate.inflate(R.layout.item_product_card_one_layout, parent, false); 130 mViewHolder.mLogoView = (CircleImageView) convertView.findViewById(R.id.item_logo_view); 131 mViewHolder.mTitleView = (TextView) convertView.findViewById(R.id.item_title_view); 132 mViewHolder.mInfoView = (TextView) convertView.findViewById(R.id.item_info_view); 133 mViewHolder.mFooterView = (TextView) convertView.findViewById(R.id.item_footer_view); 134 mViewHolder.mPriceView = (TextView) convertView.findViewById(R.id.item_price_view); 135 mViewHolder.mFromView = (TextView) convertView.findViewById(R.id.item_from_view); 136 mViewHolder.mZanView = (TextView) convertView.findViewById(R.id.item_zan_view); 137 mViewHolder.mProductLayout = (LinearLayout) convertView.findViewById(R.id.product_photo_layout); 138 break; 139 case CARD_TYPE_TWO: 140 mViewHolder = new ViewHolder(); 141 convertView = mInflate.inflate(R.layout.item_product_card_two_layout, parent, false); 142 mViewHolder.mLogoView = (CircleImageView) convertView.findViewById(R.id.item_logo_view); 143 mViewHolder.mTitleView = (TextView) convertView.findViewById(R.id.item_title_view); 144 mViewHolder.mInfoView = (TextView) convertView.findViewById(R.id.item_info_view); 145 mViewHolder.mFooterView = (TextView) convertView.findViewById(R.id.item_footer_view); 146 mViewHolder.mProductView = (ImageView) convertView.findViewById(R.id.product_photo_view); 147 mViewHolder.mPriceView = (TextView) convertView.findViewById(R.id.item_price_view); 148 mViewHolder.mFromView = (TextView) convertView.findViewById(R.id.item_from_view); 149 mViewHolder.mZanView = (TextView) convertView.findViewById(R.id.item_zan_view); 150 break; 151 case CARD_TYPE_THREE: 152 mViewHolder = new ViewHolder(); 153 convertView = mInflate.inflate(R.layout.item_product_card_three_layout, null, false); 154 mViewHolder.mViewPager = (ViewPager) convertView.findViewById(R.id.pager); 155 //add data 156 ArrayList<RecommandBodyValue> recommandList = Util.handleData(value); 157 mViewHolder.mViewPager.setPageMargin(Utils.dip2px(mContext, 12)); 158 mViewHolder.mViewPager.setAdapter(new HotSalePagerAdapter(mContext, recommandList)); 159 mViewHolder.mViewPager.setCurrentItem(recommandList.size() * 100); 160 break; 161 } 162 convertView.setTag(mViewHolder); 163 }//有tag时 164 else { 165 mViewHolder = (ViewHolder) convertView.getTag(); 166 } 167 //填充item的数据 168 switch (type) { 169 case VIDOE_TYPE: 170 mImagerLoader.displayImage(mViewHolder.mLogoView, value.logo); 171 mViewHolder.mTitleView.setText(value.title); 172 mViewHolder.mInfoView.setText(value.info.concat(mContext.getString(R.string.tian_qian))); 173 mViewHolder.mFooterView.setText(value.text); 174 mViewHolder.mShareView.setOnClickListener(new OnClickListener() { 175 @Override 176 public void onClick(View v) { 177 ShareDialog dialog = new ShareDialog(mContext, false); 178 dialog.setShareType(Platform.SHARE_VIDEO); 179 dialog.setShareTitle(value.title); 180 dialog.setShareTitleUrl(value.site); 181 dialog.setShareText(value.text); 182 dialog.setShareSite(value.title); 183 dialog.setShareTitle(value.site); 184 dialog.setUrl(value.resource); 185 dialog.show(); 186 } 187 }); 188 break; 189 case CARD_TYPE_ONE: 190 mImagerLoader.displayImage(mViewHolder.mLogoView, value.logo); 191 mViewHolder.mTitleView.setText(value.title); 192 mViewHolder.mInfoView.setText(value.info.concat(mContext.getString(R.string.tian_qian))); 193 mViewHolder.mFooterView.setText(value.text); 194 mViewHolder.mPriceView.setText(value.price); 195 mViewHolder.mFromView.setText(value.from); 196 mViewHolder.mZanView.setText(mContext.getString(R.string.dian_zan).concat(value.zan)); 197 mViewHolder.mProductLayout.setOnClickListener(new OnClickListener() { 198 @Override 199 public void onClick(View v) { 200 Intent intent = new Intent(mContext, PhotoViewActivity.class); 201 intent.putStringArrayListExtra(PhotoViewActivity.PHOTO_LIST, value.url); 202 mContext.startActivity(intent); 203 } 204 }); 205 mViewHolder.mProductLayout.removeAllViews(); 206 //动态添加多个imageview 207 for (String url : value.url) { 208 mViewHolder.mProductLayout.addView(createImageView(url)); 209 } 210 break; 211 case CARD_TYPE_TWO: 212 mImagerLoader.displayImage(mViewHolder.mLogoView, value.logo); 213 mViewHolder.mTitleView.setText(value.title); 214 mViewHolder.mInfoView.setText(value.info.concat(mContext.getString(R.string.tian_qian))); 215 mViewHolder.mFooterView.setText(value.text); 216 mViewHolder.mPriceView.setText(value.price); 217 mViewHolder.mFromView.setText(value.from); 218 mViewHolder.mZanView.setText(mContext.getString(R.string.dian_zan).concat(value.zan)); 219 //为单个ImageView加载远程图片 220 mImagerLoader.displayImage(mViewHolder.mProductView, value.url.get(0)); 221 break; 222 case CARD_TYPE_THREE: 223 break; 224 } 225 return convertView; 226 } 227 228 //自动播放方法 229 public void updateAdInScrollView() { 230 if (mAdsdkContext != null) { 231 mAdsdkContext.updateAdInScrollView(); 232 } 233 } 234 235 //动态添加ImageView 236 private ImageView createImageView(String url) { 237 ImageView photoView = new ImageView(mContext); 238 LinearLayout.LayoutParams params = new LinearLayout. 239 LayoutParams(Utils.dip2px(mContext, 100), 240 LinearLayout.LayoutParams.MATCH_PARENT); 241 params.leftMargin = Utils.dip2px(mContext, 5); 242 photoView.setLayoutParams(params); 243 mImagerLoader.displayImage(photoView, url); 244 return photoView; 245 } 246 247 private static class ViewHolder { 248 //所有Card共有属性 249 private CircleImageView mLogoView; 250 private TextView mTitleView; 251 private TextView mInfoView; 252 private TextView mFooterView; 253 //Video Card特有属性 254 private RelativeLayout mVieoContentLayout; 255 private ImageView mShareView; 256 257 //Video Card外所有Card具有属性 258 private TextView mPriceView; 259 private TextView mFromView; 260 private TextView mZanView; 261 //Card One特有属性 262 private LinearLayout mProductLayout; 263 //Card Two特有属性 264 private ImageView mProductView; 265 //Card Three特有属性 266 private ViewPager mViewPager; 267 } 268 }
3.增加listView的头布局和脚布局
3.1增加listView的头
【头布局数据】


【源码】D:\BaiduYunDownload\q0pwzp\Client_Code\app\src\main\java\com\youdu\view\course\CourseDetailHeaderView.java
1 package com.youdu.view.course; 2 3 import android.content.Context; 4 import android.content.Intent; 5 import android.graphics.Paint; 6 import android.text.TextUtils; 7 import android.util.AttributeSet; 8 import android.view.LayoutInflater; 9 import android.view.View; 10 import android.view.ViewGroup; 11 import android.widget.ImageView; 12 import android.widget.LinearLayout; 13 import android.widget.RelativeLayout; 14 import android.widget.TextView; 15 16 import com.google.gson.Gson; 17 import com.youdu.R; 18 import com.youdu.activity.PhotoViewActivity; 19 import com.youdu.core.video.VideoAdContext; 20 import com.youdu.module.course.CourseHeaderValue; 21 import com.youdu.adutil.ImageLoaderUtil; 22 import com.youdu.adutil.Utils; 23 24 import de.hdodenhof.circleimageview.CircleImageView; 25 26 public class CourseDetailHeaderView extends RelativeLayout { 27 28 private Context mContext; 29 /** 30 * UI 31 */ 32 private RelativeLayout mRootView; 33 private CircleImageView mPhotoView; 34 private TextView mNameView; 35 private TextView mDayView; 36 private TextView mOldValueView; 37 private TextView mNewValueView; 38 private TextView mIntroductView; 39 private TextView mFromView; 40 private TextView mZanView; 41 private TextView mScanView; 42 private LinearLayout mContentLayout; 43 private RelativeLayout mVideoLayout; 44 private TextView mHotCommentView; 45 /** 46 * data 47 */ 48 private CourseHeaderValue mData; 49 private ImageLoaderUtil mImageLoader; 50 51 public CourseDetailHeaderView(Context context, CourseHeaderValue value) { 52 this(context, null, value); 53 } 54 55 public CourseDetailHeaderView(Context context, AttributeSet attrs, CourseHeaderValue value) { 56 super(context, attrs); 57 mContext = context; 58 mData = value; 59 mImageLoader = ImageLoaderUtil.getInstance(mContext); 60 initView(); 61 } 62 63 private void initView() { 64 mRootView = (RelativeLayout) LayoutInflater.from(mContext). 65 inflate(R.layout.listview_course_comment_head_layout, this); 66 mPhotoView = (CircleImageView) mRootView.findViewById(R.id.photo_view); 67 mNameView = (TextView) mRootView.findViewById(R.id.name_view); 68 mDayView = (TextView) mRootView.findViewById(R.id.day_view); 69 mOldValueView = (TextView) mRootView.findViewById(R.id.old_value_view); 70 mNewValueView = (TextView) mRootView.findViewById(R.id.new_value_view); 71 mIntroductView = (TextView) mRootView.findViewById(R.id.introduct_view); 72 mFromView = (TextView) mRootView.findViewById(R.id.from_view); 73 mContentLayout = (LinearLayout) mRootView.findViewById(R.id.picture_layout); 74 mContentLayout.setOnClickListener(new OnClickListener() { 75 @Override 76 public void onClick(View v) { 77 Intent intent = new Intent(mContext, PhotoViewActivity.class); 78 intent.putStringArrayListExtra(PhotoViewActivity.PHOTO_LIST, mData.photoUrls); 79 mContext.startActivity(intent); 80 } 81 }); 82 mVideoLayout = (RelativeLayout) mRootView.findViewById(R.id.video_view); 83 mZanView = (TextView) mRootView.findViewById(R.id.zan_view); 84 mScanView = (TextView) mRootView.findViewById(R.id.scan_view); 85 mHotCommentView = (TextView) mRootView.findViewById(R.id.hot_comment_view); 86 87 mImageLoader.displayImage(mPhotoView, mData.logo); 88 mNameView.setText(mData.name); 89 mDayView.setText(mData.dayTime); 90 mOldValueView.setText(mData.oldPrice); 91 mOldValueView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG); 92 mNewValueView.setText(mData.newPrice); 93 mIntroductView.setText(mData.text); 94 mFromView.setText(mData.from); 95 mZanView.setText(mData.zan); 96 mScanView.setText(mData.scan); 97 mHotCommentView.setText(mData.hotComment); 98 /** 99 * //根据服务器返回的url的数量,动态的创建createItem(url); 100 * 然后将imageView添加到布局中; 101 */ 102 for (String url : mData.photoUrls) { 103 mContentLayout.addView(createItem(url)); 104 } 105 if (!TextUtils.isEmpty(mData.video.resource)) { 106 //调用封装好的sdk,创建视频播放器 107 new VideoAdContext(mVideoLayout, 108 new Gson().toJson(mData.video), null); 109 } 110 } 111 112 private ImageView createItem(String url) { 113 //实例化view对象; 114 ImageView imageView = new ImageView(mContext); 115 //添加布局参数; 116 LinearLayout.LayoutParams params = new LinearLayout. 117 LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.dip2px(mContext, 150)); 118 params.topMargin = Utils.dip2px(mContext, 10); 119 imageView.setLayoutParams(params); 120 imageView.setScaleType(ImageView.ScaleType.FIT_XY); 121 //加载ImageView的数据; 122 mImageLoader.displayImage(imageView, url); 123 //返回实例对象; 124 return imageView; 125 } 126 }
【布局】

1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 5 > 6 <de.hdodenhof.circleimageview.CircleImageView 7 android:id="@+id/photo_view" 8 android:layout_width="50dp" 9 android:layout_height="50dp" 10 android:layout_marginLeft="15dp" 11 android:layout_marginTop="15dp" 12 android:background="@drawable/default_user_avatar" 13 /> 14 <TextView 15 android:id="@+id/name_view" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:layout_alignTop="@id/photo_view" 19 android:layout_marginLeft="7dp" 20 android:layout_toRightOf="@id/photo_view" 21 android:text="射手宝贝" 22 android:textColor="@color/color_333333" 23 android:textSize="16sp" 24 /> 25 <TextView 26 android:id="@+id/day_view" 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:layout_alignBottom="@id/photo_view" 30 android:layout_alignLeft="@id/name_view" 31 android:text="40天前" 32 android:textColor="@color/color_999999" 33 /> 34 <TextView 35 android:id="@+id/old_value_view" 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content" 38 android:layout_alignParentRight="true" 39 android:layout_alignTop="@id/name_view" 40 android:layout_marginRight="15dp" 41 android:text="1200" 42 android:textColor="@color/color_333333" 43 android:textSize="12sp" 44 /> 45 <TextView 46 android:id="@+id/new_value_view" 47 android:layout_width="wrap_content" 48 android:layout_height="wrap_content" 49 android:layout_alignBottom="@id/day_view" 50 android:layout_alignRight="@id/old_value_view" 51 android:text="1200" 52 android:textColor="@color/color_ffff4444" 53 android:textSize="20sp" 54 /> 55 <TextView 56 android:id="@+id/introduct_view" 57 android:layout_width="match_parent" 58 android:layout_height="wrap_content" 59 android:layout_below="@id/photo_view" 60 android:layout_marginTop="20dp" 61 android:paddingLeft="15dp" 62 android:paddingRight="15dp" 63 android:text="shhdklsvklsncklsvklancklnsavksbv" 64 android:textColor="@color/color_333333" 65 android:textSize="14sp" 66 /> 67 <TextView 68 android:id="@+id/from_view" 69 android:layout_width="wrap_content" 70 android:layout_height="wrap_content" 71 android:layout_below="@id/introduct_view" 72 android:layout_marginLeft="15dp" 73 android:layout_marginTop="20dp" 74 android:drawableLeft="@drawable/icon_position" 75 android:drawablePadding="5dp" 76 android:text="来自宁波" 77 android:textColor="@color/color_ff33b5e5" 78 android:textSize="12sp" 79 /> 80 <TextView 81 android:id="@+id/danbao_view" 82 android:layout_width="wrap_content" 83 android:layout_height="wrap_content" 84 android:layout_alignParentRight="true" 85 android:layout_alignTop="@id/from_view" 86 android:layout_marginRight="15dp" 87 android:drawableLeft="@drawable/icon_alipay" 88 android:drawablePadding="5dp" 89 android:text="@string/danbao_trade" 90 android:textColor="@color/color_ff33b5e5" 91 android:textSize="12sp" 92 /> 93 94 <RelativeLayout 95 android:id="@+id/video_view" 96 android:layout_width="match_parent" 97 android:layout_height="wrap_content" 98 android:layout_below="@id/from_view" 99 android:layout_marginLeft="15dp" 100 android:layout_marginRight="15dp" 101 android:layout_marginTop="10dp" 102 /> 103 104 <LinearLayout 105 android:id="@+id/picture_layout" 106 android:layout_width="match_parent" 107 android:layout_height="wrap_content" 108 android:layout_below="@id/video_view" 109 android:layout_marginLeft="15dp" 110 android:layout_marginRight="15dp" 111 android:orientation="vertical" 112 /> 113 <View 114 android:id="@+id/divider" 115 android:layout_width="match_parent" 116 android:layout_height="0.5dp" 117 android:layout_below="@id/picture_layout" 118 android:layout_marginTop="8dp" 119 android:background="@color/color_cdcdcd" 120 /> 121 <TextView 122 android:id="@+id/zan_view" 123 android:layout_width="wrap_content" 124 android:layout_height="wrap_content" 125 android:layout_below="@id/divider" 126 android:layout_marginLeft="15dp" 127 android:layout_marginTop="10dp" 128 android:text="2人点赞" 129 android:textColor="@color/color_ff33b5e5" 130 android:textSize="13sp" 131 /> 132 <TextView 133 android:id="@+id/scan_view" 134 android:layout_width="wrap_content" 135 android:layout_height="wrap_content" 136 android:layout_alignParentRight="true" 137 android:layout_alignTop="@id/zan_view" 138 android:layout_marginRight="15dp" 139 android:text="来自宁波" 140 android:textColor="@color/color_999999" 141 android:textSize="12sp" 142 /> 143 <View 144 android:id="@+id/divider2" 145 android:layout_width="match_parent" 146 android:layout_height="14dp" 147 android:layout_below="@id/scan_view" 148 android:layout_marginTop="8dp" 149 android:background="@color/color_e3e3e3" 150 /> 151 <TextView 152 android:id="@+id/hot_comment_view" 153 android:layout_width="match_parent" 154 android:layout_height="50dp" 155 android:layout_below="@id/divider2" 156 android:gravity="center_vertical" 157 android:paddingLeft="15dp" 158 android:text="热门留言(7)" 159 android:textColor="@color/color_333333" 160 android:textSize="14sp" 161 /> 162 <View 163 android:layout_width="match_parent" 164 android:layout_height="0.5dp" 165 android:layout_below="@id/hot_comment_view" 166 android:background="@color/color_cdcdcd" 167 /> 168 </RelativeLayout>
3.2 增加listView的尾
1 package com.youdu.view.course; 2 3 import android.content.Context; 4 import android.content.Intent; 5 import android.content.res.Resources; 6 import android.util.AttributeSet; 7 import android.view.LayoutInflater; 8 import android.view.View; 9 import android.widget.ImageView; 10 import android.widget.LinearLayout; 11 import android.widget.RelativeLayout; 12 import android.widget.TextView; 13 14 import com.github.mikephil.charting.charts.LineChart; 15 import com.github.mikephil.charting.components.XAxis; 16 import com.github.mikephil.charting.components.YAxis; 17 import com.github.mikephil.charting.data.Entry; 18 import com.github.mikephil.charting.data.LineData; 19 import com.github.mikephil.charting.data.LineDataSet; 20 import com.youdu.R; 21 import com.youdu.activity.CourseDetailActivity; 22 import com.youdu.module.course.CourseFooterDateValue; 23 import com.youdu.module.course.CourseFooterRecommandValue; 24 import com.youdu.module.course.CourseFooterValue; 25 import com.youdu.util.DateFormatHelper; 26 import com.youdu.adutil.ImageLoaderUtil; 27 28 import java.util.ArrayList; 29 30 /** 31 * @author: vision 32 * @function: 33 * @date: 16/9/8 34 */ 35 public class CourseDetailFooterView extends RelativeLayout { 36 37 private Context mContext; 38 /** 39 * UI 40 */ 41 private RelativeLayout mRootView; 42 /** 43 * 图表相关UI 44 */ 45 private LinearLayout contentLayout; 46 private LineChart lineView; 47 private Resources resource; 48 private float yAxisMax = -1.0f; 49 private float yAxisMin = 100.0f; 50 private float yAxisGap = 10f; 51 private int yAxislabelNum = 5; 52 /** 53 * 推荐相关UI 54 */ 55 private ImageView[] mImageViews = new ImageView[2]; 56 private TextView[] mNameViews = new TextView[2]; 57 private TextView[] mPriceViews = new TextView[2]; 58 private TextView[] mZanViews = new TextView[2]; 59 /** 60 * data 61 */ 62 private ImageLoaderUtil mImageLoader; 63 private CourseFooterValue mFooterValue; 64 65 public CourseDetailFooterView(Context context, CourseFooterValue footerValue) { 66 this(context, null, footerValue); 67 } 68 69 public CourseDetailFooterView(Context context, AttributeSet attrs, CourseFooterValue footerValue) { 70 super(context, attrs); 71 mContext = context; 72 resource = mContext.getResources(); 73 mImageLoader = ImageLoaderUtil.getInstance(mContext); 74 mFooterValue = footerValue; 75 initView(); 76 } 77 78 private void initView() { 79 LayoutInflater inflater = LayoutInflater.from(mContext); 80 mRootView = (RelativeLayout) inflater.inflate(R.layout.listview_course_comment_footer_layout, this); 81 contentLayout = (LinearLayout) mRootView.findViewById(R.id.line_Layout); 82 mImageViews[0] = (ImageView) mRootView.findViewById(R.id.image_one_view); 83 mImageViews[1] = (ImageView) mRootView.findViewById(R.id.image_two_view); 84 mNameViews[0] = (TextView) mRootView.findViewById(R.id.name_one_view); 85 mNameViews[1] = (TextView) mRootView.findViewById(R.id.name_two_view); 86 mPriceViews[0] = (TextView) mRootView.findViewById(R.id.price_one_view); 87 mPriceViews[1] = (TextView) mRootView.findViewById(R.id.price_two_view); 88 mZanViews[0] = (TextView) mRootView.findViewById(R.id.zan_one_view); 89 mZanViews[1] = (TextView) mRootView.findViewById(R.id.zan_two_view); 90 91 for (int i = 0; i < mFooterValue.recommand.size(); i++) { 92 final CourseFooterRecommandValue value = mFooterValue.recommand.get(i); 93 mImageLoader.displayImage(mImageViews[i], value.imageUrl); 94 mImageViews[i].setOnClickListener(new OnClickListener() { 95 //跳转到新的CourseDetailActivity页面; 96 @Override 97 public void onClick(View v) { 98 Intent intent = new Intent(mContext, CourseDetailActivity.class); 99 intent.putExtra(CourseDetailActivity.COURSE_ID, value.courseId); 100 mContext.startActivity(intent); 101 } 102 }); 103 mNameViews[i].setText(value.name); 104 mPriceViews[i].setText(value.price); 105 mZanViews[i].setText(value.zan); 106 } 107 108 addLineChartView(); 109 } 110 111 /** 112 * 获取最大最小值 113 * 114 * @param currentNum 115 */ 116 private void initMaxMin(float currentNum) { 117 if (currentNum >= yAxisMax) { 118 yAxisMax = currentNum; 119 } 120 if (currentNum < yAxisMin) { 121 yAxisMin = currentNum; 122 } 123 } 124 125 /** 126 * 绘制图表 127 */ 128 private void addLineChartView() { 129 lineView = new LineChart(mContext); 130 lineView.setDescription(""); 131 lineView.setScaleEnabled(false); 132 lineView.getAxisRight().setEnabled(true); 133 lineView.setDrawGridBackground(false); 134 lineView.setTouchEnabled(false); 135 lineView.getLegend().setEnabled(false); 136 lineView.setHardwareAccelerationEnabled(true); 137 138 ArrayList<Entry> yRawData = new ArrayList<>(); 139 ArrayList<String> xRawDatas = new ArrayList<>(); 140 int index = 0; 141 for (int i = mFooterValue.time.size() - 1; i >= 0; i--) { 142 if (mFooterValue.time.get(i) != null) { 143 CourseFooterDateValue value = mFooterValue.time.get(i); 144 yRawData.add(new Entry(Float.parseFloat(value.count), index)); 145 xRawDatas.add(DateFormatHelper.formatDate(value.dt 146 .concat("000"), DateFormatHelper.DateFormat.DATE_1)); 147 index++; 148 initMaxMin(Float.parseFloat(value.count)); 149 } 150 } 151 /** 152 * x轴样式设置 153 */ 154 XAxis xAxis = lineView.getXAxis(); 155 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);// 设置x轴在底部显示 156 xAxis.setAvoidFirstLastClipping(true); 157 xAxis.setXOffset(0); // x轴间距 158 xAxis.setTextColor(resource.getColor(R.color.color_999999)); 159 xAxis.setAxisLineColor(resource.getColor(R.color.color_dddddd)); 160 xAxis.setDrawGridLines(true); 161 xAxis.setGridColor(resource.getColor(R.color.color_dddddd)); 162 /** 163 * y轴样式设置 164 */ 165 YAxis leftAxis = lineView.getAxisLeft(); 166 leftAxis.resetAxisMinValue(); 167 leftAxis.setLabelCount(yAxislabelNum, true); 168 leftAxis.setDrawLimitLinesBehindData(true); 169 leftAxis.setTextColor(resource.getColor(R.color.color_999999)); 170 leftAxis.setAxisLineColor(resource.getColor(R.color.color_dddddd)); 171 leftAxis.setDrawGridLines(true); 172 leftAxis.setGridColor(resource.getColor(R.color.color_dddddd)); 173 leftAxis.setAxisMaxValue(yAxisMax + yAxisGap); // 设置Y轴最大值 174 leftAxis.setAxisMinValue(yAxisMin - yAxisGap);// 设置Y轴最小值 175 176 YAxis rightAxis = lineView.getAxisRight(); 177 rightAxis.setDrawLabels(false); 178 rightAxis.setDrawGridLines(false); 179 rightAxis.setAxisLineColor(resource.getColor(R.color.color_dddddd)); 180 181 182 /** 183 * 曲线样式设置 184 */ 185 LineDataSet set = new LineDataSet(yRawData, ""); 186 set.setDrawCubic(true); 187 set.setCubicIntensity(0.2f); 188 set.setLineWidth(2.0f); 189 set.setColor(resource.getColor(R.color.color_fd4634)); 190 set.setCircleSize(3.0f); 191 set.setCircleColor(resource.getColor(R.color.color_fd4634)); 192 set.setFillColor(resource.getColor(R.color.color_fd4634)); 193 set.setFillAlpha(128); 194 set.setDrawFilled(true); 195 set.setDrawValues(false); 196 197 LineData data = new LineData(xRawDatas, set); 198 lineView.setData(data); 199 lineView.invalidate(); 200 201 LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 202 contentLayout.addView(lineView, params); 203 } 204 }
【布局】

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:layout_width="match_parent" 5 android:layout_height="wrap_content" 6 android:orientation="vertical" 7 > 8 <TextView 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:layout_marginLeft="15dp" 12 android:layout_marginTop="10dp" 13 android:text="@string/last_week_visti" 14 android:textColor="@color/color_333333" 15 android:textSize="15sp" 16 /> 17 <LinearLayout 18 android:id="@+id/line_Layout" 19 android:layout_width="match_parent" 20 android:layout_height="150dp" 21 android:layout_marginTop="8dp" 22 android:orientation="vertical"/> 23 24 <TextView 25 android:layout_width="wrap_content" 26 android:layout_height="wrap_content" 27 android:layout_marginBottom="10dp" 28 android:layout_marginLeft="15dp" 29 android:layout_marginTop="10dp" 30 android:text="@string/guess_you_like" 31 android:textColor="@color/color_333333" 32 android:textSize="15sp" 33 /> 34 <LinearLayout 35 android:layout_width="match_parent" 36 android:layout_height="wrap_content" 37 android:layout_marginBottom="10dp" 38 android:layout_marginLeft="15dp" 39 android:layout_marginRight="15dp" 40 android:orientation="horizontal" 41 > 42 <LinearLayout 43 android:layout_width="match_parent" 44 android:layout_height="wrap_content" 45 android:layout_marginRight="5dp" 46 android:layout_weight="1" 47 android:orientation="vertical" 48 > 49 <ImageView 50 android:id="@+id/image_one_view" 51 android:layout_width="match_parent" 52 android:layout_height="180dp" 53 /> 54 <TextView 55 android:id="@+id/name_one_view" 56 android:layout_width="wrap_content" 57 android:layout_height="wrap_content" 58 android:layout_marginTop="4dp" 59 android:text="123" 60 android:textColor="@color/color_333333" 61 android:textSize="14sp" 62 /> 63 <TextView 64 android:id="@+id/price_one_view" 65 android:layout_width="wrap_content" 66 android:layout_height="wrap_content" 67 android:layout_marginTop="4dp" 68 android:text="123" 69 android:textColor="@color/color_fd4634" 70 android:textSize="16sp" 71 /> 72 <TextView 73 android:id="@+id/zan_one_view" 74 android:layout_width="wrap_content" 75 android:layout_height="wrap_content" 76 android:layout_marginTop="4dp" 77 android:text="123" 78 android:textColor="@color/color_bfbfbf" 79 android:textSize="14sp" 80 /> 81 </LinearLayout> 82 <LinearLayout 83 android:layout_width="match_parent" 84 android:layout_height="wrap_content" 85 android:layout_marginLeft="5dp" 86 android:layout_weight="1" 87 android:orientation="vertical" 88 > 89 <ImageView 90 android:id="@+id/image_two_view" 91 android:layout_width="match_parent" 92 android:layout_height="180dp" 93 /> 94 <TextView 95 android:id="@+id/name_two_view" 96 android:layout_width="wrap_content" 97 android:layout_height="wrap_content" 98 android:layout_marginTop="4dp" 99 android:text="123" 100 android:textColor="@color/color_333333" 101 android:textSize="14sp" 102 /> 103 <TextView 104 android:id="@+id/price_two_view" 105 android:layout_width="wrap_content" 106 android:layout_height="wrap_content" 107 android:layout_marginTop="4dp" 108 android:text="123" 109 android:textColor="@color/color_fd4634" 110 android:textSize="16sp" 111 /> 112 <TextView 113 android:id="@+id/zan_two_view" 114 android:layout_width="wrap_content" 115 android:layout_height="wrap_content" 116 android:layout_marginTop="4dp" 117 android:text="123" 118 android:textColor="@color/color_bfbfbf" 119 android:textSize="14sp" 120 /> 121 </LinearLayout> 122 </LinearLayout> 123 </LinearLayout>
3.3 在UI中添加头布局和脚布局

4.Activity的启动模式



【经验之谈】
【stander模式】
【singleTop--重点】在Activity中再次启动该Activity,可以服用该Activity;减少其创建的数量;节省内存;
【singleTask--重点】在应用开启之后,只保持一个Activity的实例,Home主页必然是此模式,不会创建多个Home主页;
【singleInstance】系统级的应用会用到,全局系统的单例模式;了解即可;
【静态指定启动模式】


【配合singleTop和singleTask的使用】

【动态设置启动模式】


【效果演示】

【使用charles进行延时数据的发送】



【此时具有了延时加载】


浙公网安备 33010602011771号