編輯:關於Android編程
最近在弄個項目,要求有跑馬燈效果的圖片展示。網上搜了一堆,都沒有完美實現的算了還是自己寫吧!
實現原理利用 ViewPager 控件,這個控件本身就支持滑動翻頁很好很強大好多功能都能用上它。利用mViewPager.setCurrentItem(currentIndex); 來實現切換當前顯示的view
在加一個定時器不斷設置setCurrentItem 來實現跑馬燈效果。
一。主要實現類 注釋很詳細了 一看就知道了
package com.example.marqueeimage;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import com.example.marqueeimage.adapter.MarqueeAdapter;
import com.example.marqueeimage.transforms.ABaseTransformer;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class MarqueeImage extends LinearLayout{
private ViewPager mViewPager;
private ArrayList mPageViewList=new ArrayList();//數據??
private ImageView mImageView;
private ImageView[] mImageViews;
//主布????部指示當前頁面的小圓點視圖,LinearLayout
private ViewGroup indicatorViewGroup;
private LayoutInflater mInflater;//定義LayoutInflater
private MarqueeAdapter marqueeAdapter;//適配??
private Timer mTimer=null;//定時??
public int currentIndex=0;//當前顯示View頁面的序號
private Handler mHandler;//處理更換圖片消息
private FixedSpeedScroller scroller=null;
private Context mContext;
public MarqueeImage(Context context) {
super(context);
init(context);
}
public MarqueeImage(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
mContext=context;
LayoutInflater.from(mContext).inflate(R.layout.marquee_image, this);
mViewPager = (ViewPager) findViewById(R.id.marquee_image_viewpager);
indicatorViewGroup = (ViewGroup) findViewById(R.id.marquee_image_bottomviewgroup);
mViewPager.setOnPageChangeListener(new pageChangeListener());
mViewPager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN){
stopAutoScroller();
setScrollerTime(100);
}else if(event.getAction()==MotionEvent.ACTION_UP){
startAutoScroller();
}
return false;
}
});
marqueeAdapter=new MarqueeAdapter();
mViewPager.setAdapter(marqueeAdapter);
initHandle();
}
/**
* 設置滑動動畫
* mViewPager.setPageTransformer(true,new CubeOutTransformer());
mViewPager.setPageTransformer(true,new AccordionTransformer());
mViewPager.setPageTransformer(true,new FlipHorizontalTransformer());
mViewPager.setPageTransformer(true,new RotateUpTransformer());
mViewPager.setPageTransformer(true,new ZoomOutTranformer());
mViewPager.setPageTransformer(true,new ZoomOutSlideTransformer());
mViewPager.setPageTransformer(true,new TabletTransformer());
*/
public void setScrollerAnimation(ABaseTransformer animation){
mViewPager.setPageTransformer(true,animation);
}
/**
* 開始自動滾動
*/
public boolean startAutoScroller(){
return startTime();
}
/**
* 停止自動滾動
*/
public boolean stopAutoScroller(){
if(mTimer!=null){
mTimer.cancel();
mTimer=null;
return true;
}else{
return false;
}
}
/**
* 初始化Handle
*/
public void initHandle(){
mHandler = new Handler() {
@SuppressLint("NewApi") public void handleMessage(Message msg) {
if(msg.what==1){
setScrollerTime(700);
mViewPager.setCurrentItem(currentIndex);
if(mPageViewList.size()-1==currentIndex){
currentIndex=0;
}else{
currentIndex++;
}
}
};
};
}
/**
* 設置滑動時間
*/
public void setScrollerTime(int scrollerTime){
try {
if(scroller!=null){
scroller.setTime(scrollerTime);
}else{
Field mScroller;
mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
scroller= new FixedSpeedScroller(mViewPager.getContext(),new AccelerateInterpolator());
scroller.setTime(scrollerTime);
mScroller.set(mViewPager, scroller);
}
} catch (Exception e) {
}
}
/**
* 創建底部的導航條
*/
public void createNavBar(){
mImageViews = new ImageView[mPageViewList.size()];
for (int i = 0; i < mImageViews.length; i++) {
mImageView = new ImageView(mContext);
mImageView.setLayoutParams(new LayoutParams(20,20));
mImageView.setPadding(20, 0, 20, 0);
if (i == 0) {
mImageView.setBackgroundResource(R.drawable.page_indicator_focused);
} else {
mImageView.setBackgroundResource(R.drawable.page_indicator);
}
mImageViews[i] = mImageView;
//把指示作用的遠點圖片加入底部的視圖中
indicatorViewGroup.addView(mImageViews[i]);
}
}
class pageChangeListener implements OnPageChangeListener{
@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
for (int i = 0; i < mImageViews.length; i++) {
if(i == arg0) {
mImageViews[i].setBackgroundResource(R.drawable.page_indicator_focused);
} else {
mImageViews[i].setBackgroundResource(R.drawable.page_indicator);
}
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
}
/**
* 啟動計時
*/
private boolean startTime(){
if(mTimer==null){
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
Message msg=new Message();
msg.what=1;
mHandler.sendMessage(msg);
}
},2000,2000); //每2秒執行一次
return true;
}else{
return false;
}
}
/**
* 設置數據
* @param mPageViews
*/
public void setData(ArrayList pageViewList){
if(pageViewList!=null){
this.mPageViewList=pageViewList;
marqueeAdapter.setData(mPageViewList);//添加數據
marqueeAdapter.notifyDataSetChanged();//通知數據發生改變??
createNavBar();//根據數據,創建導航條
}
}
/**
* 清理全部數據
*/
public void clearData(){
if(this.mPageViewList!=null){
this.mPageViewList.clear();
}
mViewPager.removeAllViews();
indicatorViewGroup.removeAllViews();
}
}
二。ViewPager的適配器也很簡單
package com.example.marqueeimage.adapter; import java.util.ArrayList; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.View; /** * @author fcm * @Create at 2013-8-27 下午2:48:34 * @Version 1.0 *三。控制滑動速度 這個很重要 設置自動滾動默認的速度的很快 效果很差,用FixedSpeedScroller繼承Scroller來實現控制viewpaper滑動速度 這部分來自網絡Features draft description. 主要功能介紹
*/ public class MarqueeAdapter extends PagerAdapter{ private ArrayListmPageViews=new ArrayList (); /** * 添加數據 * @param mPageViews */ public void setData(ArrayList mPageViews){ this.mPageViews=mPageViews; } @Override public int getCount() { return mPageViews.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public int getItemPosition(Object object) { // TODO Auto-generated method stub return super.getItemPosition(object); } @Override public void destroyItem(View arg0, int arg1, Object arg2) { // TODO Auto-generated method stub ((ViewPager) arg0).removeView(mPageViews.get(arg1)); } @Override public Object instantiateItem(View arg0, int arg1) { // TODO Auto-generated method stub ((ViewPager) arg0).addView(mPageViews.get(arg1)); return mPageViews.get(arg1); } @Override public void restoreState(Parcelable arg0, ClassLoader arg1) { // TODO Auto-generated method stub } @Override public Parcelable saveState() { // TODO Auto-generated method stub return null; } @Override public void startUpdate(View arg0) { // TODO Auto-generated method stub } @Override public void finishUpdate(View arg0) { // TODO Auto-generated method stub } }
package com.example.marqueeimage;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.animation.Interpolator;
import android.widget.Scroller;
public class FixedSpeedScroller extends Scroller {
private int mDuration =500;
public void setTime(int scrollerTime){
mDuration=scrollerTime;
}
public FixedSpeedScroller(Context context) {
super(context);
}
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@SuppressLint("NewApi") public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) {
super(context, interpolator, flywheel);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
}
四。布局文件:
五。 最後一步就是修改默認動畫,實現比較絢麗的效果 這部分來自網絡 大約有10種左右動畫吧
源碼下載地址:http://download.csdn.net/download/nn955/7465547
Android 使用ListView實現網易評論蓋樓效果
效果如下:(點擊下載demo) 實現原理:頂部利用了ListView的HeadView來實現,然後其他每個item都用背景實現! 首先設置一些常量:package c
Android ListView詳解
ListView 控件可使用四種不同視圖顯示項目。通過此控件,可將項目組成帶有或不帶有列標頭的列,並顯示伴隨的圖標和文本。 可使用 ListView 控件將稱作 List
Android設置頁面的設計
在Android 的程序中設置項可以說是一個必須要有的頁面。下面說一下如何寫一個基本的設置頁面。我們先來看一下常用安卓程序的設置頁面:
Android Application Fundamentals——Android應用程序基礎知識
Application Fundamentals——應用程序基礎知識Key classes——關鍵類Activ