学习技术最好的方式就是实战,看书看不到的东西太多了,实际操作时会碰到各种书本里提不到的问题,解决这些问题会迅速提升你的能力,你是一个solider,最好成长的方式就是实战。下面我们介绍一下个人做的一个小DEMO:JAVA关键字学习,这可以简单的理解成一本电子书,却也用到了一些技术,有助于初学者提升自己的能力。
进入程序的第一个图用于介绍作用:
第二个页面就进入正题了介绍了Abstract关键字:
总结了一下:本小DEMO共用到了以下几点技术:
1.怎么解决多文字文本的排版问题;
2.怎么更好的实现手势翻页;
3.怎么实现Intent跳转动画效果;
4.怎么实现TTS;
5.如何实现程序开始的动画效果。
下面我们来一一解决这些问题,关于怎么解决多文字文本的排版问题,我想到了html结合webview的方式实现,事先做好html页面,存于asset文件夹下,用webview控件展示html,这样文本效果更好。
关于第二点,为什么说更好的手势翻页?我们知道手势翻页会用到GestureDetector类,为什么讲更好的实现,请看下面的代码,
我们以第一页为例:
package org.yayun.keywordReader; import java.util.Locale; import net.youmi.android.AdManager; import net.youmi.android.banner.AdSize; import net.youmi.android.banner.AdView; import net.youmi.android.spot.SpotManager; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Typeface; import android.os.Bundle; import android.speech.tts.TextToSpeech; import android.util.Log; import android.view.Display; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.Window; import android.view.WindowManager; import android.webkit.WebView; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; public class Abstract_activity extends Activity { private TextToSpeech tts; private ImageButton ImageButton01; private WebView webView = null; private GestureDetector detector; private TextView textView = null; private TextView yinbiaoTextView = null; private int mWidth; public boolean onCreateOptionsMenu(Menu menu) {// !!!!!!!!!!!!�? menu.add(Menu.NONE, Menu.FIRST + 1, 0, "退出").setIcon(null); menu.add(Menu.NONE, Menu.FIRST + 2, 1, "关于我们").setIcon(null); menu.add(Menu.NONE, Menu.FIRST + 3, 2, "检测更新").setIcon(null); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) {// !!!!!!!!!!!!�? switch (item.getItemId()) { case Menu.FIRST + 1: finish(); break; case Menu.FIRST + 2: break; case Menu.FIRST + 3: break; default: break; } return false; } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 生命周期方法 SpotManager.getInstance(this).loadSpotAds(); SpotManager.getInstance(this).showSpotAds(this); AdManager.getInstance(this).init("c5fbddafb37a478e", "eee1729b466a9d36", false); requestWindowFeature(Window.FEATURE_NO_TITLE);// 填充标题�? super.setContentView(R.layout.abstract_layout); // 设置要使用的布局管理�? AdView adView = new AdView(this, AdSize.FIT_SCREEN);// 加入广告 LinearLayout adLayout = (LinearLayout) findViewById(R.id.adLayout);// 加入广告 adLayout.addView(adView);// 加入广告 tts = new TextToSpeech(this, ttsInitListener); ImageButton01 = (ImageButton) this.findViewById(R.id.ImageButton01); detector = new GestureDetector(new GestureListener()); this.textView = (TextView) super.findViewById(R.id.mytext); this.yinbiaoTextView = (TextView) super.findViewById(R.id.yinbiao); Typeface mFace = Typeface.createFromAsset(getAssets(), "font/segoeui.ttf"); yinbiaoTextView.setTypeface(mFace); yinbiaoTextView.setText("[ˈæbˌstrækt]"); this.textView.setText("Abstract"); this.webView = (WebView) super.findViewById(R.id.myview); webView.loadUrl("file:///android_asset/abstract.html"); this.webView.setOnTouchListener(new TouchListener()); this.webView.setLongClickable(true); ImageButton01.setOnClickListener(new ImageButton.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub /* 传入要说的字符串 */ tts.speak("abstract", TextToSpeech.QUEUE_FLUSH, null); } }); mWidth = Abstract_activity.getScreenWidth(this); } // 获取屏幕 private TextToSpeech.OnInitListener ttsInitListener = new TextToSpeech.OnInitListener() { public void onInit(int status) { // TODO Auto-generated method stub /* 使用美国时区目前不支持中�? */ Locale loc = new Locale("us", "", ""); /* �?查是否支持输入的时区 */ if (tts.isLanguageAvailable(loc) == TextToSpeech.LANG_AVAILABLE) { /* 设定语言 */ tts.setLanguage(loc); } tts.setOnUtteranceCompletedListener(ttsUtteranceCompletedListener); } }; private TextToSpeech.OnUtteranceCompletedListener ttsUtteranceCompletedListener = new TextToSpeech.OnUtteranceCompletedListener() { public void onUtteranceCompleted(String utteranceId) { // TODO Auto-generated method stub } }; @Override protected void onDestroy() { tts.shutdown(); super.onDestroy(); } public static int getScreenWidth(Context context) { WindowManager manager = null; try { manager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); Log.d("11", "cuowu1 "); } Display display = manager.getDefaultDisplay(); return display.getWidth(); } private class TouchListener implements OnTouchListener { public boolean onTouch(View v, MotionEvent event) { return detector.onTouchEvent(event); } } private int minVelocity = 0; public class GestureListener implements OnGestureListener { public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (e1.getX() - e2.getX() > mWidth / 3 && Math.abs(velocityX) > minVelocity) { // 切换Activity Log.d("11", "verticalMinDistance "); Intent intent = new Intent(Abstract_activity.this, Assert_activity.class); startActivity(intent); overridePendingTransition(R.anim.fade, R.anim.hold); // Toast.makeText(Abstract_activity.this, "向左手势", // Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > mWidth / 3 && Math.abs(velocityX) > minVelocity) { Toast.makeText(Abstract_activity.this, "第一页!", Toast.LENGTH_SHORT).show(); } return false; } } }
我们看这一段代码:
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (e1.getX() - e2.getX() > mWidth / 3 && Math.abs(velocityX) > minVelocity) { // 切换Activity Log.d("11", "verticalMinDistance "); Intent intent = new Intent(Abstract_activity.this, Assert_activity.class); startActivity(intent); overridePendingTransition(R.anim.fade, R.anim.hold); // Toast.makeText(Abstract_activity.this, "向左手势", // Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > mWidth / 3 && Math.abs(velocityX) > minVelocity) { Toast.makeText(Abstract_activity.this, "第一页!", Toast.LENGTH_SHORT).show(); } return false; }
这一段代码是实现手势翻页的关键代码,其中e1代表手势起始点事件,e2代表手势结束点事件,e1.getX()-e2.getX()可以理解为手划过的像素点数,一般的文章都是固定了他们的大小,比如100,或200,这样在实际使用中如果用户的手机分辨率很高的话,用户体验效果就极差,容易误操作,也就是向下翻页的时候很容易切换页面。我们考虑到这个问题,首先用方法:
public static int getScreenWidth(Context context) { WindowManager manager = null; try { manager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); Log.d("11", "cuowu1 "); } Display display = manager.getDefaultDisplay(); return display.getWidth(); }
获取屏幕的宽度像素,然后在onFling()方法中将e2.getX() - e1.getX() 和mWidth / 3作比较也就是三分之一屏幕作为参照,这样就能保证在任何分辨率的手机上只有划过三分之一的屏幕才能实现翻页,能有效的防止在低分辨屏幕中的误操作事件。
对于第三点如何实现Intent跳转中的动画效果,应该来讲比较简单,我们实现向后翻页的动画效果,
Android 平台提供了两类动画。 一类是Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果(旋转、平移、放缩和渐变)。
第二类就是 Frame动画,即顺序的播放事先做好的图像,与gif图片原理类似。
一般用到第一类:
Tweene Animations。
主要类:
Animation 动画
AlphaAnimation 渐变透明度
RotateAnimation 画面旋转
ScaleAnimation 渐变尺寸缩放
TranslateAnimation 位置移动
AnimationSet 动画集
动画效果很多,可以查相关文章,这里我们只是简单的介绍一下如何加入动画,新建两个xml文件:
fade.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator" > <scale android:duration="800" android:fromXScale="0.1" android:fromYScale="0.1" android:pivotX="50%p" android:pivotY="50%p" android:toXScale="1.0" android:toYScale="1.0" /> <!-- 这里为了看到动画演示效果,把动画持续时间设为0.3秒 --> <alpha android:duration="800" android:fromAlpha="0.1" android:toAlpha="1.0" /> </set>
hold.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator" android:zAdjustment="top" > <scale android:duration="800" android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="50%p" android:pivotY="50%p" android:toXScale=".5" android:toYScale=".5" /> <!-- 系统内置的动画持续时间 android:duration="@android:integer/config_mediumAnimTime" --> <alpha android:duration="800" android:fromAlpha="1.0" android:toAlpha="0" /> </set>
做好了动画文件,如何加入呢?很简单,只需在Intent跳转后加入一句:overridePendingTransition(R.anim.fade, R.anim.hold);
内容较多,下一篇文章继续讨论。
我的应用: http://openbox.mobilem.360.cn/index/d/sid/2966005
http://android.myapp.com/myapp/detail.htm?apkName=com.yayun.gitlearning
欢迎下载,有问题多交流!