Android自定义控件eBook实现翻书效果实例详解

本文实例讲述了Android自定义控件eBook实现翻书效果的方法。分享给大家供大家参考,具体如下:

效果图:

Book.java文件:

package com.book;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
public class Book extends Activity {
  /** Called when the activity is first created. */
 eBook mBook;
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mBook = (eBook)findViewById(R.id.my_book);
    mBook.addLayoutRecForPage(R.layout.page,21);
    mBook.setListener(new eBook.Listener() {
  public void onPrevPage() {
  updateContent();
  }
  public void onNextPage() {
  updateContent();
  }
  public void onInit() {
  updateContent();
  }
 });
  }
  private void updateContent(){
   int index = mBook.getIndexForLeftPage();
   View left = mBook.getLeftPage(),right = mBook.getRightPage();
    View next1 = mBook.getNextPage1(),next2 = mBook.getNextPage2();
    View prev1 = mBook.getPrevPage1(),prev2 = mBook.getPrevPage2();
    if(left != null)setImg(left,index);
    if(right != null)setImg(right,index+1);
    if(next1 != null)setImg(next1,index+2);
    if(next2 != null)setImg(next2,index+3);
    if(prev1 != null)setImg(prev1,index-1);
    if(prev2 != null)setImg(prev2,index-2);
    mBook.invalidate();
  }
 private void setImg(View v , int index){
 if(index >= 0 && index < 20){
  ImageView img = (ImageView)v.findViewById(R.id.book_img);
  if(img == null)return;
  Log.d("eBook","set Img");
  switch(index%6){
  case 0:
  img.setImageResource(R.drawable.p1);
  break;
  case 1:
  img.setImageResource(R.drawable.p2);
  break;
  case 2:
  img.setImageResource(R.drawable.p3);
  break;
  case 3:
  img.setImageResource(R.drawable.p4);
  break;
  case 4:
  img.setImageResource(R.drawable.p5);
  break;
  case 5:
  img.setImageResource(R.drawable.p6);
  break;
  default:
  break;
  }
 }
 }
}

main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
 <com.book.eBook android:id="@+id/my_book"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"/>
</LinearLayout>

page.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:padding="20dip"
  android:background="#FFFFDD">
  <ImageView android:layout_width="fill_parent" android:id="@+id/book_img"
  android:layout_height="fill_parent" android:layout_weight="1"
  android:scaleType="fitXY" android:src="http://wallage.blog.163.com/blog/@drawable/p1"/>
  <com.book.TelEdit
  android:id="@+id/book_text"
  android:layout_width="fill_parent"
  android:background="#ffffdd"
  android:gravity="top"
  android:typeface="sans"
  android:capitalize="sentences"
  android:lineSpacingExtra="5dip"
  android:textSize="15dip"
  android:textColor="#000000"
  android:layout_height="fill_parent"
  android:paddingTop="30dip"
  android:layout_weight="1"/>
</LinearLayout>

控件TelEdit.java代码:

package com.book;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.WindowManager;
import android.widget.EditText;
public class TelEdit extends EditText {
 Context mContext;
 public TelEdit(Context context) {
 super(context);
 mContext = context;
 }
 public TelEdit(Context context, AttributeSet attrs) {
 super(context, attrs);
 mContext = context;
 }
 public TelEdit(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 mContext = context;
 }
 protected void onDraw(Canvas canvas) {
 WindowManager wm = (WindowManager) mContext.getSystemService("window");
 int windowWidth = wm.getDefaultDisplay().getWidth();
 int windowHeight = wm.getDefaultDisplay().getHeight();
 Paint paint = new Paint();
 paint.setStyle(Paint.Style.FILL);
 paint.setColor(Color.BLACK);
 int paddingTop = getPaddingTop();
 int paddingBottom = getPaddingBottom();
 int scrollY = getScrollY();
 int scrollX = getScrollX() + windowWidth;
 int innerHeight = scrollY + getHeight() - paddingBottom;
 int lineHeight = getLineHeight();
 int baseLine = scrollY
  + (lineHeight - ((scrollY - paddingTop) % lineHeight));
 int x = 8;
 while (baseLine < innerHeight) {
  canvas.drawLine(x, baseLine, scrollX - x, baseLine, paint);
  baseLine += lineHeight;
 }
 super.onDraw(canvas);
 }
}

eBook.java文件部分代码:

package com.book;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class eBook extends FrameLayout{
 public static final String LOG_TAG = "eBook";
 List<Integer> myRecPages;
 int totalPageNum;
 Context mContext;
 boolean hasInit = false;
 final int defaultWidth = 600 , defaultHeight = 400;
 int contentWidth = 0;
 int contentHeight = 0;
 View leftPage,rightPage,llPage,lrPage,rrPage,rlPage;
 LinearLayout mView;
 bookView mBookView;
 boolean closeBook = false;
 private enum Corner {
 LeftTop,
 RightTop,
 LeftBottom,
 RightBottom,
 None
 };
 private Corner mSelectCorner;
 final int clickCornerLen = 250*250; //50dip
 float scrollX = 0,scrollY = 0;
 int indexPage = 0;
 private enum State {
 ABOUT_TO_ANIMATE,
 ANIMATING,
 ANIMATE_END,
 READY,
 TRACKING
 };
 private State mState;
 private Point aniStartPos;
 private Point aniStopPos;
 private Date aniStartTime;
 private long aniTime = 2000;
 private long timeOffset = 900;
 Listener mListener;
 private GestureDetector mGestureDetector;
 private BookOnGestureListener mGestureListener;
 public eBook(Context context) {
 super(context);
 Init(context);
 }
 public eBook(Context context, AttributeSet attrs) {
 super(context, attrs);
 Init(context);
 }
...省略
}

该控件大致实现方法:

eBook继承FrameLayout,好处在于FrameLayout有图层效果,后添加的View类能覆盖前面的View。

初始化:定义一个LinearLayout的成员变量mView,将page.xml inflate 成View分别用leftPage,rightPage引用,并初始化其数据,将leftPage,rightPage通过addView添加到mView,然后将mView添加到eBook。在eBook里定义一个私有类BookView extends View。 并定义成员变量 BookView mBookView; 最后将mBookView添加的eBook中,这样,mView中的内容为书面内容,mBookView中的内容为特效内容。

后续手势动作:可将各种手势的特效动作画于mBookView的画布中。

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android图形与图像处理技巧总结》、《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android多媒体操作技巧汇总(音频,视频,录音等)》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

(0)

相关推荐

  • Android中okhttp3.4.1+retrofit2.1.0实现离线缓存

    关于Retrofit+OkHttp的强大这里就不多说了,还没了解的同学可以自行去百度.这篇文章主要讲如何利用Retrofit+OkHttp来实现一个较为简单的缓存策略: 即有网环境下我们请求数据时,如果没有缓存或者缓存过期了,就去服务器拿数据,并且将新缓存保存下来,如果有缓存而且没有过期,则直接使用缓存.无网环境下我们请求数据时,缓存没过期则直接使用缓存,缓存过期了则无法使用,需要重新联网获取服务器数据. 缓存处理还是很有必要的,它有效的减少服务器负荷,降低延迟提升用户体验,同时也方便用户即使在

  • Android基于反射技术实现的加减乘除运算示例

    本文实例讲述了Android基于反射技术实现的加减乘除运算.分享给大家供大家参考,具体如下: JAVA反射机制定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法

  • Android Style.xml的应用详解及代码实现

    Style.xml的妙用 Style.xml之于Android犹如css之于Jsp 妙用 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layou

  • Android自定义EditText右侧带图片控件

    前言 最近项目做用户登录模块需要一个右边带图片的EditText,图片可以设置点击效果,所以就查资料做了一个自定义EditText出来,方便以后复用. 原理 下面是自定义EditText的代码,具体难点是要实现图片的点击监听,因为谷歌官方至今没有给出一个直接实现EditText里面图片的监听API.我的做法是整个控件绑定一个OnTouchListener,然后监测点击事件,检测点击位置的X坐标是否在图片的覆盖范围内(下面getCompoundDrawables()[2]里面的2是代表图片在Edi

  • Android编程之阴影(Shadow)制作方法

    本文实例讲述了Android编程之阴影(Shadow)制作方法.分享给大家供大家参考,具体如下: 先看运行效果图如下: 阴影制作:包括各种形状(矩形,圆形等等),以及文字等等都能设置阴影. 阴影制作是什么原理呢? 其实很简单,你需要设置阴影的东西被看作一个主层.然后在主层下面画一个阴影层. 阴影制作涉及到一个重要函数: public void setShadowLayer (float radius, float dx, float dy, int color) 参数: radius:阴影半径

  • 超精准的Android手机计步器开发

    亲测在小米.魅族.华为上可用,该app采用后台service计歩服务,所以只要app不被手机杀死在后台也是可以正常计歩的.上图: 1.需要在AndroidManifest.xml中添加权限 <!--计歩需要的权限--> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.WRI

  • Android实现的截屏小程序示例

    本文实例讲述了Android实现的截屏小程序.分享给大家供大家参考,具体如下: 先看截图,不过这个截屏还不够完整,头上的statusbar没有,呈黑色. 多按了几次,就成这样了,呵呵. package com.test; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Bitmap.Config; import

  • Android自定义View获取注册验证码倒计时按钮

    在Android开发中,我们不可避免的会做到注册功能,而现在的注册大多数都是用手机去注册的,那么注册的时候都会要求用获取验证码的方式去验证,我们接下来就来实战一下自定义获取验证码倒计时按钮: 1.先看效果图 2.我们涉及到的变量 //倒计时时长,可设置 /** * 倒计时时长,默认倒计时时间60秒: */ private long length = 60 * 1000; //在点击按钮之前按钮所显示的文字 /** * 在点击按钮之前按钮所显示的文字,默认是获取验证码 */ private Str

  • Android自定义控件eBook实现翻书效果实例详解

    本文实例讲述了Android自定义控件eBook实现翻书效果的方法.分享给大家供大家参考,具体如下: 效果图: Book.java文件: package com.book; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; public class Book extend

  • Android ImageView的selector效果实例详解

    Android ImageView的selector效果实例详解 在平时开发中如Button我们给它加上selector分别呈现pressed以及normal效果能给我们的用户体验上大大增色不少,可是我们当我们是用ImageView来"当作"一个一个"Button"的时候发现直接设置selector却不起作用,当然此时我们的应用就表现的暗淡了.那我们就只能找到方法来解决这种情况. 首先定义一个selector文件: <selector xmlns:androi

  • Android自定义View中attrs.xml的实例详解

    Android自定义View中attrs.xml的实例详解 我们在自定义View的时候通常需要先完成attrs.xml文件 在values中定义一个attrs.xml 然后添加相关属性 这一篇先详细介绍一下attrs.xml的属性. <?xml version="1.0" encoding="utf-8"?> <resources> //自定义属性名,定义公共属性 <attr name="titleText" for

  • Bootstrap与KnockoutJs相结合实现分页效果实例详解

    KnockoutJS是一个JavaScript实现的MVVM框架.非常棒.比如列表数据项增减后,不需要重新刷新整个控件片段或自己写JS增删节点,只要预先定义模板和符合其语法定义的属性即可.简单的说,我们只需要关注数据的存取. 一.引言 由于最近公司的系统需要改版,改版的新系统我打算使用KnockoutJs来制作Web前端.在做的过程中,遇到一个问题--如何使用KnockoutJs来完成分页的功能.在前一篇文章中并没有介绍使用KnockoutJs来实现分页,所以在这篇文章中,将补充用Knockou

  • Android 动态注册监听网络变化实例详解

    Android 动态注册监听网络变化实例详解 新建一个BroadcastTest项目,然后修改MainActivity中的代码,如下: public class MainActivity extends AppCompatActivity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle

  • Android 图片存入系统相册更新显示实例详解

    Android 图片存入系统相册更新显示实例详解 在开发android的过程中,我们避免不了可能会涉及到做一个自定义相册或则会去本地创建一个文件夹来存储我们需要的图片.拿相册来说,比如我们创建一个test的文件夹,拍完一张照片后存储到这个指定的test文件夹里,然后在相册里面显示出来,就像微信的效果一样.拍完即可立即显示.但是,在实际开发过程中我们保存完一张图片后并不能立即更新显示出来这个图片,需要我们重启手机才能在系统相册中显示出来. 这里先提供一个插入系统图库的方法: MediaStore.

  • Android开发高仿课程表的布局实例详解

    先说下这个demo,这是一个模仿课程表的布局文件,虽然我是个菜鸟,但我还是想留给学习的人一些例子,先看下效果 然后再来看一下我们学校的app 布局分析 先上一张划分好了的布局图 首先整个页面放在一个LinearLayout布局下面,分为上面和下面两个部分,下面一个是显示课程表的详细信息 1:这个没什么好讲的,就是直接一个LinearLayout布局,然后将控件一个TextView用来显示年份,一个View用来当作竖线,一个Spinner用来显示选择周数 2:这个是显示星期几的部件,是我自定义的V

  • 微信小程序 利用css实现遮罩效果实例详解

    微信小程序 利用css实现遮罩效果实例详解 实现效果图: 如图所示,使用css实现小程序的遮罩效果,代码如下 js文件代码: //index.js //获取应用实例 var app = getApp() Page({ data: { flag: false }, a: function(){ this.setData({flag: false}) }, b: function(){ this.setData({flag: true}) } }) wxss文件代码: .b1{position:fi

  • Android ListView中动态添加RaidoButton的实例详解

    Android ListView中动态添加RaidoButton的实例详解 这里讲解的内容是:从数据库中取得数据,将这些数据的value值赋值给Radiobutton的text属性,将这些数据的key值赋值给radiobutton的key值.同时实现点击一整行,更换radiobutton选择. XML代码:主要是添加一个ListView控件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&q

  • Android 监听软键盘状态的实例详解

    Android 监听软键盘状态的实例详解 近日遇到要检测软键盘是否显示或隐藏的问题,搜了一下网上,最后找到一个很简单的,记录一下. activityRoot是activity的根view,就是xml里面的第一个view,给它设置一个id. final View activityRootView = findViewById(R.id.activityRoot); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(ne

随机推荐