android真实项目教程(六)——落叶醉赤壁_by_CJJ

大家晚上好,我是cjj,今天不讲废话,因为我被“忙”了。。。
今晚主要把关于的界面(aboutFragment)完成了。。。效果很好哦 (自吹一下)。。。呵呵。。。其中有两个比较好的效果。 一、 PullScrollView,仿照新浪微博Android客户端个人中心的ScrollView,下拉背景伸缩回弹效果。它还有一种效果是仿IOS回弹效果。 二、点击列表,慢慢张开一个View的自定义动画(animation)。。。
android真实项目教程(一)——App应用框架搭建_by_CJJ http://www.apkbus.com/forum.php?mod=viewthread&tid=166151
android真实项目教程(二)——漫画App初构_by_CJJ http://www.apkbus.com/forum.php?mod=viewthread&tid=166262
android真实项目教程(三)——首页初点缀_by_CJJ http://www.apkbus.com/forum.php?mod=viewthread&tid=166630
android真实项目教程(四)——MY APP MY STYLE_by_CJJ http://www.apkbus.com/forum.php?mod=viewthread&tid=167676
android真实项目教程(五)——有时三点两点雨_by_CJJ http://www.apkbus.com/forum.php?mod=viewthread&tid=168422

看下效果吧:




主要源码:
  1. package com.cjj.shopapp.fragment;


  2. import android.os.Bundle;
  3. import android.support.v4.app.Fragment;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.view.ViewGroup;
  8. import android.view.animation.Animation;
  9. import android.view.animation.Animation.AnimationListener;
  10. import android.view.animation.RotateAnimation;
  11. import android.widget.ImageView;
  12. import android.widget.TextView;
  13. import android.widget.Toast;

  14. import com.cjj.shopapp.activity.R;
  15. import com.cjj.shopapp.animation.ExpandAnimation;
  16. import com.cjj.shopapp.custom.view.PullScrollView;
  17. import com.cjj.shopapp.custom.view.PullScrollView.OnTurnListener;

  18. /**
  19. * 关于界面
  20. *
  21. * @author Administrator
  22. *
  23. */
  24. public class AboutFragment extends Fragment implements OnClickListener,
  25. OnTurnListener {
  26. private final int MAX_LINES = 4;
  27. private boolean isClickable = false;
  28. private TextView tv_info, tv_load_more;
  29. // 自定义的scrollview
  30. private PullScrollView mPullScrollView;
  31. // about 背景图
  32. private ImageView img_bigShopLogo;

  33. private TextView tv_Contact;
  34. private TextView tv_ContactContent;

  35. private boolean isAnimEnd = true;

  36. private ImageView img_otherContactArrow;

  37. @Override
  38. public void onActivityCreated(Bundle savedInstanceState) {
  39. mPullScrollView.init(img_bigShopLogo);
  40. mPullScrollView.setOnTurnListener(AboutFragment.this);
  41. super.onActivityCreated(savedInstanceState);
  42. }

  43. @Override
  44. public void onCreate(Bundle savedInstanceState) {
  45. super.onCreate(savedInstanceState);
  46. }

  47. @Override
  48. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  49. Bundle savedInstanceState) {
  50. View v = inflater.inflate(R.layout.fragment_about, null);
  51. return v;
  52. }

  53. @Override
  54. public void onDestroyView() {
  55. super.onDestroyView();
  56. }

  57. @Override
  58. public void onViewCreated(View view, Bundle savedInstanceState) {
  59. super.onViewCreated(view, savedInstanceState);
  60. tv_info = (TextView) view.findViewById(R.id.tv_info);
  61. tv_info.setMaxLines(MAX_LINES);
  62. tv_load_more = (TextView) view.findViewById(R.id.tv_loadmore);
  63. tv_load_more.setOnClickListener(this);

  64. mPullScrollView = (PullScrollView) view.findViewById(R.id.sv_about);
  65. img_bigShopLogo = (ImageView) view.findViewById(R.id.img_bigShopLogo);

  66. tv_Contact = (TextView) view.findViewById(R.id.tv_otherContact);
  67. tv_Contact.setOnClickListener(this);
  68. tv_ContactContent = (TextView) view
  69. .findViewById(R.id.tv_otherContactContent);

  70. img_otherContactArrow = (ImageView) view
  71. .findViewById(R.id.img_otherContactArrow);
  72. img_otherContactArrow.measure(0, 0);
  73. }

  74. @Override
  75. public void onClick(View v) {
  76. switch (v.getId()) {
  77. case R.id.tv_loadmore:
  78. if (!isClickable) {
  79. tv_info.setMaxLines(tv_info.getLineCount());
  80. tv_load_more.setText("收起");
  81. isClickable = true;
  82. } else {
  83. tv_info.setMaxLines(MAX_LINES);
  84. tv_load_more.setText("查看更多");
  85. isClickable = false;
  86. }
  87. break;
  88. case R.id.tv_otherContact:

  89. if (isAnimEnd) {

  90. if (tv_ContactContent.getVisibility() == View.GONE) {
  91. rotateArrow(0, 90);
  92. } else {
  93. rotateArrow(90, 0);
  94. }

  95. ExpandAnimation mAnimation = new ExpandAnimation(
  96. tv_ContactContent);
  97. mAnimation.setAnimationListener(new ExpandAnimationListener());
  98. tv_ContactContent.startAnimation(mAnimation);
  99. }
  100. }
  101. }

  102. /** 防止用户频繁操作 */
  103. private class ExpandAnimationListener implements AnimationListener {

  104. @Override
  105. public void onAnimationStart(Animation animation) {

  106. isAnimEnd = false;
  107. }

  108. @Override
  109. public void onAnimationEnd(Animation animation) {

  110. isAnimEnd = true;
  111. }

  112. @Override
  113. public void onAnimationRepeat(Animation animation) {

  114. }
  115. }

  116. /**
  117. * 旋转指示器
  118. *
  119. * @param fromDegrees
  120. * @param toDegrees
  121. */
  122. private void rotateArrow(float fromDegrees, float toDegrees) {
  123. RotateAnimation mRotateAnimation = new RotateAnimation(fromDegrees,
  124. toDegrees,
  125. (int) (img_otherContactArrow.getMeasuredWidth() / 2.0),
  126. (int) (img_otherContactArrow.getMeasuredHeight() / 2.0));
  127. mRotateAnimation.setDuration(150);
  128. mRotateAnimation.setFillAfter(true);
  129. img_otherContactArrow.startAnimation(mRotateAnimation);
  130. }

  131. @Override
  132. public void onTurn() {
  133. Toast.makeText(getActivity(), "拼命拉拉有惊喜哦!", 1000).show();
  134. }

  135. }
复制代码
  1. package com.cjj.shopapp.custom.view;

  2. import android.content.Context;
  3. import android.graphics.Rect;
  4. import android.util.AttributeSet;
  5. import android.view.MotionEvent;
  6. import android.view.View;
  7. import android.view.animation.TranslateAnimation;
  8. import android.widget.ImageView;
  9. import android.widget.ScrollView;

  10. import com.cjj.shopapp.utils.ScreenUtils;

  11. /**
  12. * 自定义ScrollView
  13. *
  14. * @author MarkMjw
  15. * [url=home.php?mod=space&uid=354393]@DATE[/url] 2013-09-13
  16. */
  17. public class PullScrollView extends ScrollView {
  18. /** 阻尼系数,越小阻力就越大. */
  19. private static final float SCROLL_RATIO = 0.35f;

  20. /** 滑动至翻转的距离. */
  21. private static final int TURN_DISTANCE = 50;

  22. /** 头部图片. */
  23. private ImageView mHeadImage;

  24. /** 头部图片显示高度. */
  25. private int mHeadImageH;

  26. /** 孩子View. */
  27. private View mChildView;

  28. /** ScrollView的孩子View矩形. */
  29. private Rect mRect = new Rect();

  30. /** 首次点击的Y坐标. */
  31. private float mTouchDownY;

  32. /** 是否关闭ScrollView的滑动. */
  33. private boolean mEnableTouch = false;

  34. /** 是否开始移动. */
  35. private boolean isMoving = false;

  36. /** 头部图片初始顶部和底部. */
  37. private int mInitTop, mInitBottom;

  38. /** 头部图片拖动时顶部和底部. */
  39. private int mCurrentTop, mCurrentBottom;

  40. /** 状态变化时的监听器. */
  41. private OnTurnListener mOnTurnListener;

  42. /** 状态:上部,下部,默认. */
  43. private enum State {
  44. UP, DOWN, NORMAL
  45. }

  46. /** 状态. */
  47. private State state = State.NORMAL;

  48. public PullScrollView(Context context) {
  49. super(context);
  50. }

  51. public PullScrollView(Context context, AttributeSet attrs) {
  52. super(context, attrs);
  53. }

  54. public PullScrollView(Context context, AttributeSet attrs, int defStyle) {
  55. super(context, attrs, defStyle);
  56. }

  57. /**
  58. * 初始化
  59. *
  60. * @param imageView 头部图片
  61. */
  62. public void init(ImageView imageView) {
  63. mHeadImage = imageView;
  64. mHeadImageH = ScreenUtils.dipConvertPx(94);
  65. }

  66. /**
  67. * 设置状态改变时的监听器
  68. *
  69. * @param turnListener
  70. */
  71. public void setOnTurnListener(OnTurnListener turnListener) {
  72. mOnTurnListener = turnListener;
  73. }

  74. /**
  75. * 根据 XML 生成视图工作完成.该函数在生成视图的最后调用,在所有子视图添加完之后.
  76. * 即使子类覆盖了 onFinishInflate 方法,也应该调用父类的方法,使该方法得以执行.
  77. */
  78. @Override
  79. protected void onFinishInflate() {
  80. if (getChildCount() > 0) {
  81. mChildView = getChildAt(0);
  82. }
  83. }

  84. @Override
  85. protected void onScrollChanged(int l, int t, int oldl, int oldt) {
  86. super.onScrollChanged(l, t, oldl, oldt);

  87. // 当滚动到顶部时,将状态设置为正常,避免先向上拖动再向下拖动到顶端后首次触摸不响应的问题
  88. if (getScrollY() == 0) {
  89. state = State.NORMAL;
  90. }
  91. }

  92. @Override
  93. public boolean onTouchEvent(MotionEvent ev) {
  94. if (mChildView != null) {
  95. doTouchEvent(ev);
  96. }

  97. // 禁止控件本身的滑动.
  98. if (mEnableTouch) {
  99. return true;
  100. } else {
  101. return super.onTouchEvent(ev);
  102. }
  103. }

  104. /**
  105. * 触摸事件处理
  106. *
  107. * @param event
  108. */
  109. private void doTouchEvent(MotionEvent event) {
  110. int action = event.getAction();

  111. switch (action) {
  112. case MotionEvent.ACTION_DOWN:
  113. mTouchDownY = event.getY();

  114. if(mHeadImage!=null)
  115. {
  116. mCurrentTop = mInitTop = mHeadImage.getTop();
  117. mCurrentBottom = mInitBottom = mHeadImage.getBottom();
  118. }
  119. break;

  120. case MotionEvent.ACTION_MOVE:
  121. float deltaY = event.getY() - mTouchDownY;

  122. doActionMove(deltaY);
  123. break;

  124. case MotionEvent.ACTION_UP:
  125. // 回滚动画
  126. if (isNeedAnimation()) {
  127. rollBackAnimation();
  128. }

  129. if (getScrollY() == 0) {
  130. state = State.NORMAL;
  131. }

  132. isMoving = false;
  133. mEnableTouch = false;
  134. break;

  135. default:
  136. break;
  137. }
  138. }

  139. /**
  140. * 执行移动动画
  141. *
  142. * @param deltaY
  143. */
  144. private void doActionMove(float deltaY) {
  145. // 对于首次Touch操作要判断方位:UP OR DOWN
  146. if (deltaY < 0 && state == State.NORMAL) {
  147. state = State.UP;
  148. } else if (deltaY > 0 && state == State.NORMAL) {
  149. state = State.DOWN;
  150. }

  151. if (state == State.UP) {
  152. deltaY = deltaY < 0 ? deltaY : 0;

  153. isMoving = false;
  154. mEnableTouch = false;

  155. } else if (state == State.DOWN) {
  156. if (getScrollY() <= deltaY) {
  157. mEnableTouch = true;
  158. isMoving = true;
  159. }
  160. deltaY = deltaY < 0 ? 0 : deltaY;
  161. }

  162. if (isMoving) {
  163. // 初始化头部矩形
  164. if (mRect.isEmpty()) {
  165. // 保存正常的布局位置
  166. mRect.set(mChildView.getLeft(), mChildView.getTop(), mChildView.getRight(),
  167. mChildView.getBottom());
  168. }

  169. // 移动背景图(手势移动的距离*阻尼系数*0.5)
  170. float bgMoveH = deltaY * 0.5f * SCROLL_RATIO;
  171. mCurrentTop = (int) (mInitTop + bgMoveH);
  172. mCurrentBottom = (int) (mInitBottom + bgMoveH);

  173. if(mHeadImage!=null)
  174. {
  175. mHeadImage.layout(mHeadImage.getLeft(), mCurrentTop, mHeadImage.getRight(), mCurrentBottom);
  176. }

  177. // 移动布局(手势移动的距离*阻尼系数)
  178. float childMoveH = deltaY * SCROLL_RATIO;

  179. // 修正移动的距离,避免超过图片的底边缘
  180. int top = mCurrentBottom - mHeadImageH;
  181. if (mRect.top + childMoveH > top) {
  182. childMoveH -= mRect.top + childMoveH - top;
  183. }

  184. mChildView.layout(mRect.left, (int) (mRect.top + childMoveH),
  185. mRect.right, (int) (mRect.bottom + childMoveH));
  186. }
  187. }

  188. /**
  189. * 回滚动画
  190. */
  191. private void rollBackAnimation() {
  192. TranslateAnimation image_Anim = new TranslateAnimation(0, 0,
  193. Math.abs(mInitTop - mCurrentTop), 0);
  194. image_Anim.setDuration(200);

  195. if(mHeadImage!=null)
  196. {
  197. mHeadImage.startAnimation(image_Anim);

  198. mHeadImage.layout(mHeadImage.getLeft(), mInitTop, mHeadImage.getRight(), mInitBottom);

  199. }

  200. // 开启移动动画
  201. TranslateAnimation inner_Anim = new TranslateAnimation(0, 0, mChildView.getTop(), mRect.top);
  202. inner_Anim.setDuration(200);
  203. mChildView.startAnimation(inner_Anim);
  204. mChildView.layout(mRect.left, mRect.top, mRect.right, mRect.bottom);

  205. mRect.setEmpty();

  206. // 回调监听器
  207. if (mCurrentTop > mInitTop + TURN_DISTANCE && mOnTurnListener != null){
  208. mOnTurnListener.onTurn();
  209. }
  210. }

  211. /**
  212. * 是否需要开启动画
  213. */
  214. private boolean isNeedAnimation() {
  215. return !mRect.isEmpty() && isMoving;
  216. }

  217. /**
  218. * 执行翻转
  219. *
  220. * @author MarkMjw
  221. */
  222. public interface OnTurnListener {
  223. /**
  224. * 翻转回调方法
  225. */
  226. public void onTurn();
  227. }
  228. }
复制代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#f0f0f0"
  6. android:fadingEdge="none"
  7. android:gravity="center"
  8. android:orientation="vertical" >

  9. <TextView
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content"
  12. android:drawableLeft="@drawable/qq"
  13. android:ellipsize="end"
  14. android:gravity="center_horizontal"
  15. android:shadowDx="3.0"
  16. android:shadowDy="3.0"
  17. android:shadowRadius="5.0"
  18. android:singleLine="true"
  19. android:text="^_^ 拉拉更健康。。。"
  20. android:textColor="@color/tv_blue"
  21. android:textSize="20sp" />

  22. <ImageView
  23. android:id="@+id/img_bigShopLogo"
  24. android:layout_width="match_parent"
  25. android:layout_height="275dp"
  26. android:layout_marginTop="-55dp"
  27. android:contentDescription="@null"
  28. android:scaleType="fitXY"
  29. android:src="@drawable/about_bg4" />

  30. <com.cjj.shopapp.custom.view.PullScrollView
  31. android:id="@+id/sv_about"
  32. android:layout_width="match_parent"
  33. android:layout_height="match_parent"
  34. android:fadingEdge="none"
  35. android:fillViewport="true" >

  36. <LinearLayout
  37. android:layout_width="match_parent"
  38. android:layout_height="match_parent"
  39. android:orientation="vertical" >

  40. <RelativeLayout
  41. android:layout_width="match_parent"
  42. android:layout_height="wrap_content"
  43. android:layout_marginTop="80dp" >

  44. <LinearLayout
  45. android:id="@+id/ll_top"
  46. android:layout_width="match_parent"
  47. android:layout_height="25dp"
  48. android:background="@android:color/transparent"
  49. android:orientation="horizontal" />

  50. <LinearLayout
  51. android:layout_width="match_parent"
  52. android:layout_height="wrap_content"
  53. android:layout_below="@id/ll_top"
  54. android:background="@color/app_default_bg_f5"
  55. android:orientation="vertical" >

  56. <FrameLayout
  57. android:id="@+id/user_divider_layout"
  58. android:layout_width="match_parent"
  59. android:layout_height="wrap_content"
  60. android:layout_marginLeft="21dp"
  61. android:layout_marginRight="21dp"
  62. android:layout_marginTop="50dp" >

  63. <ImageView
  64. android:layout_width="match_parent"
  65. android:layout_height="1px"
  66. android:layout_marginTop="5dp"
  67. android:background="#DFDFDF"
  68. android:contentDescription="@null" />

  69. <ImageView
  70. android:layout_width="wrap_content"
  71. android:layout_height="wrap_content"
  72. android:layout_marginLeft="29dp"
  73. android:contentDescription="@null"
  74. android:src="@drawable/line_arrow_up" />
  75. </FrameLayout>

  76. <TextView
  77. android:id="@+id/tv_info"
  78. android:layout_width="match_parent"
  79. android:layout_height="wrap_content"
  80. android:layout_marginBottom="5dp"
  81. android:layout_marginTop="5dp"
  82. android:maxLines="5"
  83. android:paddingLeft="10dp"
  84. android:paddingRight="10dp"
  85. android:text="@string/about_intro"
  86. android:textColor="@color/cs_66"
  87. android:textSize="15sp" />

  88. <TextView
  89. android:id="@+id/tv_loadmore"
  90. android:layout_width="match_parent"
  91. android:layout_height="wrap_content"
  92. android:layout_marginBottom="5dp"
  93. android:gravity="center_vertical|right"
  94. android:paddingLeft="21dp"
  95. android:paddingRight="21dp"
  96. android:text="查看更多 "
  97. android:textColor="@color/tv_blue"
  98. android:textSize="15sp" />

  99. <FrameLayout
  100. android:layout_width="match_parent"
  101. android:layout_height="wrap_content" >

  102. <TextView
  103. android:id="@+id/tv_otherContact"
  104. android:layout_width="match_parent"
  105. android:layout_height="48dp"
  106. android:layout_gravity="center"
  107. android:layout_marginTop="-2dp"
  108. android:background="@drawable/card_whole"
  109. android:gravity="center_vertical|left"
  110. android:padding="10dp"
  111. android:text="联系方式 "
  112. android:textColor="#515151"
  113. android:textSize="15sp" />

  114. <ImageView
  115. android:id="@+id/img_otherContactArrow"
  116. android:layout_width="wrap_content"
  117. android:layout_height="wrap_content"
  118. android:layout_gravity="center_vertical|right"
  119. android:layout_marginRight="10dp"
  120. android:src="@drawable/jiantou_down" />
  121. </FrameLayout>

  122. <TextView
  123. android:id="@+id/tv_otherContactContent"
  124. android:layout_width="match_parent"
  125. android:layout_height="wrap_content"
  126. android:drawableLeft="@drawable/qq"
  127. android:drawablePadding="4dp"
  128. android:gravity="center_vertical|left"
  129. android:padding="6dp"
  130. android:text="QQ : 929178101"
  131. android:textColor="@color/tv_blue"
  132. android:textSize="16sp"
  133. android:visibility="gone"
  134. />

  135. <TextView
  136. android:id="@+id/tv_mainSales"
  137. android:layout_width="match_parent"
  138. android:layout_height="48dp"
  139. android:background="@drawable/card_whole"
  140. android:gravity="center_vertical|left"
  141. android:padding="10dp"
  142. android:text="SUMMARY : MY APP MY STYLE _by_CJJ"
  143. android:textColor="@color/tv_blue"
  144. android:textSize="16sp" />
  145. </LinearLayout>

  146. <ImageView
  147. android:id="@+id/img_shopLogo"
  148. android:layout_width="68dp"
  149. android:layout_height="68dp"
  150. android:layout_marginLeft="21dp"
  151. android:background="@android:color/white"
  152. android:contentDescription="@null"
  153. android:padding="1px"
  154. android:scaleType="fitXY"
  155. android:src="@drawable/icon_about" />

  156. <TextView
  157. android:id="@+id/tv_shopName"
  158. android:layout_width="wrap_content"
  159. android:layout_height="wrap_content"
  160. android:layout_marginLeft="13dp"
  161. android:layout_toRightOf="@id/img_shopLogo"
  162. android:ellipsize="end"
  163. android:shadowColor="@android:color/black"
  164. android:shadowDx="3.0"
  165. android:shadowDy="3.0"
  166. android:shadowRadius="5.0"
  167. android:singleLine="true"
  168. android:text="CJJ漫画"
  169. android:textColor="@color/white"
  170. android:textSize="20sp" />

  171. <TextView
  172. android:id="@+id/tv_phone"
  173. android:layout_width="wrap_content"
  174. android:layout_height="wrap_content"
  175. android:layout_below="@+id/tv_shopName"
  176. android:layout_marginLeft="103dp"
  177. android:layout_marginTop="4dp"
  178. android:ellipsize="end"
  179. android:singleLine="true"
  180. android:text=" V1.0"
  181. android:textColor="@color/cs_66"
  182. android:textSize="16sp" />
  183. </RelativeLayout>
  184. </LinearLayout>
  185. </com.cjj.shopapp.custom.view.PullScrollView>

  186. </RelativeLayout>
复制代码
很多细节的东西你只要看下源码就懂了呵呵 ,今晚就说这些了。。。我写烦人的论文去。。。
源码:
本帖隐藏的内容
由于文件太大,没有把库文件传上来,你可以在之前的文章中找到: CartoonAppCjj.zip(15.52 MB, 下载次数: 17)
我上传到csdn的下载网址(完整版):http://download.csdn.net/detail/junjichen/7267101

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值