天天看點

android自定義flipview翻頁,Android自定義ViewFlipper實作滾動效果

本文執行個體為大家分享了自定義view實作了類似百度手機助手,首頁評論滾動效果。

看效果:

gif做的不好,其效果就是:幾個viewitem不停的向上滾動,新加入item有個淡入的效果。

說下實作思路:自定義view繼承至LinearLayout,控制item數量及其動畫效果,實作item複用,傳入資料即可,使用友善。

代碼:

public class ViewFlipper extends LinearLayout {

private final int MAX_SHOW_ITEM_SIZE = 5;

private IAdapter mIAdapter;

private int mCount;

//最後一個item動畫

private Animation mLastOneAnimation;

//其它item動畫

private Animation mCommonAnimation;

//資料下标

private int mCurrentIndex;

private static final int DEFAULT_INTERVAL = 2000;

private int mFlipInterval = DEFAULT_INTERVAL;

private boolean mAutoStart = false;

private boolean mRunning = false;

private boolean mStarted = false;

private boolean mVisible = false;

private boolean mUserPresent = true;

public ViewFlipper(Context context) {

super(context);

init(context);

}

public ViewFlipper(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public ViewFlipper(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(context);

}

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

final String action = intent.getAction();

if (Intent.ACTION_SCREEN_OFF.equals(action)) {

mUserPresent = false;

updateRunning();

} else if (Intent.ACTION_USER_PRESENT.equals(action)) {

mUserPresent = true;

updateRunning(false);

}

}

};

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

// Listen for broadcasts related to user-presence

final IntentFilter filter = new IntentFilter();

filter.addAction(Intent.ACTION_SCREEN_OFF);

filter.addAction(Intent.ACTION_USER_PRESENT);

// OK, this is gross but needed. This class is supported by the

// remote views machanism and as a part of that the remote views

// can be inflated by a context for another user without the app

// having interact users permission - just for loading resources.

// For exmaple, when adding widgets from a user profile to the

// home screen. Therefore, we register the receiver as the current

// user not the one the context is for.

getContext().registerReceiver(mReceiver, filter);

if (mAutoStart) {

// Automatically start when requested

startFlipping();

}

}

@Override

protected void onDetachedFromWindow() {

super.onDetachedFromWindow();

mVisible = false;

getContext().unregisterReceiver(mReceiver);

updateRunning();

}

@Override

protected void onWindowVisibilityChanged(int visibility) {

super.onWindowVisibilityChanged(visibility);

mVisible = visibility == VISIBLE;

updateRunning(mVisible);

// updateRunning(false);

}

private void init(Context context) {

this.setOrientation(LinearLayout.VERTICAL);

}

public void setIAdapter(IAdapter iAdapter) {

this.mIAdapter = iAdapter;

initShowItems();

}

public void startFlipping() {

mStarted = true;

updateRunning();

}

public void stopFlipping() {

mStarted = false;

updateRunning();

}

private void updateRunning() {

updateRunning(true);

}

public boolean isFlipping() {

return mStarted;

}

public void setAutoStart(boolean autoStart) {

mAutoStart = autoStart;

}

public boolean isAutoStart() {

return mAutoStart;

}

@Override

public void onInitializeAccessibilityEvent(AccessibilityEvent event) {

super.onInitializeAccessibilityEvent(event);

event.setClassName(ViewFlipper.class.getName());

}

@Override

public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {

super.onInitializeAccessibilityNodeInfo(info);

info.setClassName(ViewFlipper.class.getName());

}

private void initShowItems() {

if (mIAdapter != null) {

mCount = mIAdapter.getCount();

for (int i = 0; i < mCount; i++) {

if (i == MAX_SHOW_ITEM_SIZE) {

break;

}

View convertView = getChildAt(i);

View item = mIAdapter.getItemView(convertView, i);

addView(item, i);

}

}

}

private void updateRunning(boolean flipNow) {

boolean running = mVisible && mStarted && mUserPresent;

System.out.println(" updateRunning running:" + running + " mVisible " + mVisible + " userPresent " + mUserPresent);

if (running != mRunning) {

if (running && (mCount > MAX_SHOW_ITEM_SIZE)) {

showItems(mCurrentIndex++, flipNow);

Message msg = mHandler.obtainMessage(FLIP_MSG);

mHandler.sendMessageDelayed(msg, mFlipInterval);

} else {

mHandler.removeMessages(FLIP_MSG);

}

mRunning = running;

}

}

private void showItems(final int position, boolean animate) {

if (animate && (mLastOneAnimation == null || mCommonAnimation == null)) {

mLastOneAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.lastone_anim);

mCommonAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.common_anim);

}

int childCount = getChildCount();

for (int i = 0; i < childCount; i++) {

View child = getChildAt(i);

child.clearAnimation();

int index = position + i;

child = mIAdapter.getItemView(child, (index >= mIAdapter.getCount()) ? (index - mIAdapter.getCount()) : index);

if (animate) {

if (i == childCount - 1) {

child.setAnimation(mLastOneAnimation);

} else {

child.setAnimation(mCommonAnimation);

}

}

child.setVisibility(View.VISIBLE);

}

if (animate) {

mCommonAnimation.startNow();

mLastOneAnimation.startNow();

}

//保證傳入的position小于getCount

if (mCurrentIndex >= mIAdapter.getCount()) {

mCurrentIndex = 0;

}

}

private final int FLIP_MSG = 1;

private final Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

if (msg.what == FLIP_MSG) {

if (mRunning) {

showItems(mCurrentIndex++, true);

msg = obtainMessage(FLIP_MSG);

sendMessageDelayed(msg, mFlipInterval);

}

}

}

};

public interface IAdapter {

public View getItemView(View convertView, int position);

public int getCount();

}

}

再來看看調用部分:

public class MainActivity extends ActionBarActivity implements ViewFlipper.IAdapter {

ViewFlipper viewFlipper;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

viewFlipper = (ViewFlipper) findViewById(R.id.view_flipper);

viewFlipper.setIAdapter(this);

}

@Override

protected void onResume() {

super.onResume();

viewFlipper.startFlipping();

}

@Override

public View getItemView(View convertView, int position) {

View item = null;

TextView textView;

if (convertView == null) {

item = View.inflate(this, R.layout.item, null);

} else {

item = convertView;

}

textView = (TextView) item.findViewById(R.id.textview);

textView.setText("測試資料:" + position);

return item;

}

@Override

public int getCount() {

return 8;

}

}

可以看出,MainActivity實作了ViewFlipper.IAdapter接口,setAdapter後調用startFlipper即可。

這裡布局檔案我就不貼出來了,附上工程源碼,項目裡動畫時間有點長,修改下就ok。

限于水準有限,不足之處難免,望各位不舍指正,與君共勉。

以上就是本文的全部内容,希望對大家的學習有所幫助,也希望大家多多支援腳本之家。