您的位置:首页 > 编程语言 > Java开发

java 接口interface的使用

2011-10-14 14:27 645 查看
首先:创建一个接口类, 里面只有一个空方法,没有方法体:

package com.lp.scroll;

public interface SelectPoint{

public void changeSelectedPoint(int position);

}

然后,在实现改接口的类中定义该接口中方法具体要做的事情:

package com.lp.scroll;

import java.util.ArrayList;

import java.util.List;

import android.content.Context;

import android.util.AttributeSet;

import android.widget.ImageView;

import android.widget.LinearLayout;

import com.lp.R;

public class ScrollPoints extends LinearLayout implements SelectPoint {

private List<ImageView> points = new ArrayList<ImageView>();

private LinearLayout pointBox;

public ScrollPoints(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

}

public void initPoints(Context context, int count, int selected) {

pointBox = new LinearLayout(context);

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

ImageView slidePot = new ImageView(context);

slidePot.setPadding(5, 5, 5, 5);

if (i == selected) {

slidePot.setBackgroundResource(R.drawable.slide_pot_selected);

} else {

slidePot.setBackgroundResource(R.drawable.slide_pot);

}

points.add(slidePot);

pointBox.addView(slidePot);

}

addView(pointBox);

}

public void addPoint(Context context, int count){

if(count > points.size()){

ImageView slidePot = new ImageView(context);

slidePot.setPadding(5, 5, 5, 5);

points.add(slidePot);

pointBox.addView(slidePot);

}

}

@Override

public void changeSelectedPoint(int position) {

for (int i = 0; i < points.size(); i++) {

ImageView point = points.get(i);

if (i == position) {

point.setBackgroundResource(R.drawable.slide_pot_selected);

} else {

point.setBackgroundResource(R.drawable.slide_pot);

}

}

}

}

第三步:在触发该接口事件的类中定义一个方法,把接口实例传入:

package com.lp.scroll;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

import android.app.Activity;

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.MotionEvent;

import android.view.VelocityTracker;

import android.view.View;

import android.view.ViewConfiguration;

import android.view.ViewGroup;

import android.widget.GridView;

import android.widget.Scroller;

import com.lp.R;

import com.lp.adapter.CategoryAdapter;

/**

* 仿Launcher中的WorkSapce,可以左右滑动切换屏幕的类

*/

public class ScrollLayout extends ViewGroup {

private static final String TAG = "ScrollLayout";

private static final int CATEGORY_COUNT_PER_SCREEN = 9;

private Scroller mScroller;

private VelocityTracker mVelocityTracker;

private int mCurScreen;

private int mDefaultScreen = 0;

private static final int TOUCH_STATE_REST = 0;

private static final int TOUCH_STATE_SCROLLING = 1;

private static final int SNAP_VELOCITY = 600;

private int mTouchState = TOUCH_STATE_REST;

private int mTouchSlop;

private float mLastMotionX;

private float mLastMotionY;

private SelectPoint changePoint = null;

private Map<String, Integer> categories;

private boolean viewChanged = false;

public ScrollLayout(Context context, AttributeSet attrs) {

this(context, attrs, 0);

// TODO Auto-generated constructor stub

}

public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

mScroller = new Scroller(context);

// 默认显示第一屏

mCurScreen = mDefaultScreen;

mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

if (changed || viewChanged) {

viewChanged = false;

int childLeft = 0;

final int childCount = getChildCount();

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

final View childView = getChildAt(i);

if (childView.getVisibility() != View.GONE) {

final int childWidth = childView.getMeasuredWidth();

childView.layout(childLeft, 0, childLeft + childWidth,

childView.getMeasuredHeight());

childLeft += childWidth;

// 很明显 0 - 320 | 320 - 640 | 640 - 960 ...(假设屏幕宽320)

}

}

}

}

@Override

public void addView(View child) {

super.addView(child);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

Log.e(TAG, "onMeasure");

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

final int width = MeasureSpec.getSize(widthMeasureSpec);

final int widthMode = MeasureSpec.getMode(widthMeasureSpec);

if (widthMode != MeasureSpec.EXACTLY) {

throw new IllegalStateException(

"ScrollLayout only canmCurScreen run at EXACTLY mode!");

}

final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

if (heightMode != MeasureSpec.EXACTLY) {

throw new IllegalStateException(

"ScrollLayout only can run at EXACTLY mode!");

}

// The children are given the same width and height as the scrollLayout

final int count = getChildCount();

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

getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);

}

// Log.e(TAG, "moving to screen "+mCurScreen);

// x坐标 y坐标

// 移动到第几屏

scrollTo(mCurScreen * width, 0);

}

/**

* According to the position of current layout scroll to the destination

* page. 判断滑动的位置 如果大于当前屏中间的位置 则换屏 否则 仍然是这个屏 getScrollX x方向的偏移量

*/

public void snapToDestination() {

final int screenWidth = getWidth();

// 判断

final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;

snapToScreen(destScreen);

}

public void snapToScreen(int whichScreen) {

// get the valid layout page

whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));

if (getScrollX() != (whichScreen * getWidth())) {

final int delta = whichScreen * getWidth() - getScrollX();

// 开始滚动

// x,y,x方向移动量,y方向移动量,滚动持续时间,负数往左滚

mScroller.startScroll(getScrollX(), 0, delta, 0,

Math.abs(delta) * 2);

mCurScreen = whichScreen;

invalidate(); // Redraw the layout

changePoint.changeSelectedPoint(mCurScreen);

}

}

public void setToScreen(int whichScreen) {

whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));

mCurScreen = whichScreen;

scrollTo(whichScreen * getWidth(), 0);

}

public int getCurScreen() {

return mCurScreen;

}

public int getScreenCount() {

return getChildCount();

}

// 只有当前LAYOUT中的某个CHILD导致SCROLL发生滚动,才会致使自己的COMPUTESCROLL被调用

@Override

public void computeScroll() {

// TODO Auto-generated method stub

Log.e(TAG, "computeScroll");

// 如果返回true,表示动画还没有结束

// 因为前面startScroll,所以只有在startScroll完成时 才会为false

if (mScroller.computeScrollOffset()) {

Log.e(TAG, mScroller.getCurrX() + "======" + mScroller.getCurrY());

// 产生了动画效果 每次滚动一点

scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

postInvalidate();

}

}

@Override

public boolean onTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

Log.e(TAG, "onTouchEvent start");

if (mVelocityTracker == null) {

mVelocityTracker = VelocityTracker.obtain();

}

mVelocityTracker.addMovement(event);

final int action = event.getAction();

final float x = event.getX();

final float y = event.getY();

switch (action) {

case MotionEvent.ACTION_DOWN:

Log.e(TAG, "event down! " + mScroller.isFinished());

// 如果屏幕的滚动动画没有结束 你就按下了 就结束动画

if (!mScroller.isFinished()) {

mScroller.abortAnimation();

}

mLastMotionX = x;

break;

case MotionEvent.ACTION_MOVE:

Log.e(TAG, "event move!");

// 取得偏移量

int deltaX = (int) (mLastMotionX - x);

Log.e(TAG, "detaX: " + deltaX);

mLastMotionX = x;

// x方向的偏移量 y方向的偏移量

scrollBy(deltaX, 0);

break;

case MotionEvent.ACTION_UP:

Log.e(TAG, "event : up");

// if (mTouchState == TOUCH_STATE_SCROLLING) {

final VelocityTracker velocityTracker = mVelocityTracker;

velocityTracker.computeCurrentVelocity(1000);

int velocityX = (int) velocityTracker.getXVelocity();

Log.e(TAG, "velocityX:" + velocityX);

if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {

// Fling enough to move left

Log.e(TAG, "snap left");

snapToScreen(mCurScreen - 1);

} else if (velocityX < -SNAP_VELOCITY

&& mCurScreen < getChildCount() - 1) {

// Fling enough to move right

Log.e(TAG, "snap right");

snapToScreen(mCurScreen + 1);

} else {

// 一般都掉用这个

snapToDestination();

}

if (mVelocityTracker != null) {

mVelocityTracker.recycle();

mVelocityTracker = null;

}

// }

mTouchState = TOUCH_STATE_REST;

break;

case MotionEvent.ACTION_CANCEL:

mTouchState = TOUCH_STATE_REST;

break;

}

return true;

}

// 这个感觉没什么作用 不管true还是false 都是会执行onTouchEvent的 因为子view里面onTouchEvent返回false了

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

// TODO Auto-generated method stub

Log.e(TAG, "onInterceptTouchEvent-slop:" + mTouchSlop);

final int action = ev.getAction();

if ((action == MotionEvent.ACTION_MOVE)

&& (mTouchState != TOUCH_STATE_REST)) {

return true;

}

final float x = ev.getX();

final float y = ev.getY();

switch (action) {

case MotionEvent.ACTION_MOVE:

Log.e(TAG, "onInterceptTouchEvent move");

final int xDiff = (int) Math.abs(mLastMotionX - x);

if (xDiff > mTouchSlop) {

mTouchState = TOUCH_STATE_SCROLLING;

}

break;

case MotionEvent.ACTION_DOWN:

Log.e(TAG, "onInterceptTouchEvent down");

mLastMotionX = x;

mLastMotionY = y;

Log.e(TAG, mScroller.isFinished() + "");

mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST

: TOUCH_STATE_SCROLLING;

break;

case MotionEvent.ACTION_CANCEL:

case MotionEvent.ACTION_UP:

Log.e(TAG, "onInterceptTouchEvent up or cancel");

mTouchState = TOUCH_STATE_REST;

break;

}

Log.e(TAG, mTouchState + "====" + TOUCH_STATE_REST);

return mTouchState != TOUCH_STATE_REST;

}

/**

* @param chacgePoint

* the chacgePoint to set

*/

public void setChacgePoint(SelectPoint changePoint) {

this.changePoint = changePoint;

}

public void setCategories(Map<String, Integer> categories) {

this.categories = categories;

}

public void initScreen(Activity activity, LayoutInflater inflater) {

if (categories == null) {

return;

}

Set<Entry<String, Integer>> entrySet = categories.entrySet();

int i = 0;

int totalScreenNum = categories.size() / CATEGORY_COUNT_PER_SCREEN;

int currentScreen = 0;

Map<String, Integer> oneScreenCategories = null;

for (Iterator<Entry<String, Integer>> it = entrySet.iterator(); it

.hasNext();) {

// 9 category icons in one screen

if (i % CATEGORY_COUNT_PER_SCREEN == 0) {

currentScreen++;

if (oneScreenCategories != null) {

GridView child = (GridView) inflater.inflate(

R.layout.single_screen, null);

child.setAdapter(new CategoryAdapter(activity,

oneScreenCategories));

addView(child);

}

oneScreenCategories = new LinkedHashMap<String, Integer>();

}

// create map for last category screen

if (currentScreen > totalScreenNum + 1) {

oneScreenCategories = new LinkedHashMap<String, Integer>();

}

// put every 9 category objects into one map

Map.Entry<String, Integer> entry = (Entry<String, Integer>) it

.next();

oneScreenCategories.put(entry.getKey(), entry.getValue());

// add last category screen

if (i == categories.size() - 1) {

GridView child = (GridView) inflater.inflate(

R.layout.single_screen, null);

child.setAdapter(new CategoryAdapter(activity,

oneScreenCategories));

addView(child);

}

i++;

}

}

public void addCategory(Activity activity, LayoutInflater inflater,

String categoryName, Integer categoryIconId) {

categories.put(categoryName, categoryIconId);

CategoryAdapter adapter = (CategoryAdapter) ((GridView) getChildAt(getChildCount() - 1))

.getAdapter();

int categoryCount = adapter.getCount();

if (categoryCount < CATEGORY_COUNT_PER_SCREEN) {

// add to last screen

adapter.addCategory(categoryName, categoryIconId);

adapter.notifyDataSetChanged();

} else {

// create a new screen

Map<String, Integer> categories = new LinkedHashMap<String, Integer>();

categories.put(categoryName, categoryIconId);

GridView child = (GridView) inflater.inflate(

R.layout.single_screen, null);

child.setAdapter(new CategoryAdapter(activity, categories));

addView(child);

}

viewChanged = true;

}

}

最后:把接口实例set进触发接口事件的实例:

package com.lp;

import java.util.LinkedHashMap;

import java.util.Map;

import android.app.Activity;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import com.lp.scroll.ScrollLayout;

import com.lp.scroll.ScrollPoints;

public class D_multiScreenActivity extends Activity implements OnClickListener {

private LayoutInflater mInflater;

private ScrollLayout mScrollLayout;

private ScrollPoints mScrollPoints;

private Button btnAddCategory;

private Map<String, Integer> categories;

private int num = 0;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mInflater = LayoutInflater.from(this);

mScrollLayout = (ScrollLayout) findViewById(R.id.ScrollLayoutTest);

mScrollPoints = (ScrollPoints) findViewById(R.id.scrollPoints);

btnAddCategory = (Button) findViewById(R.id.addCategory);

btnAddCategory.setOnClickListener(this);

// fake data

categories = new LinkedHashMap<String, Integer>();

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

categories.put("my cate" + i, R.drawable.icon);

}

// initial category by map

mScrollLayout.setCategories(categories);

mScrollLayout.initScreen(this, mInflater);

// set interface

mScrollLayout.setChacgePoint(mScrollPoints);

// add footer points

mScrollPoints.initPoints(this, mScrollLayout.getScreenCount(),

mScrollLayout.getCurScreen());

}

@Override

public void onClick(View v) {

num++;

mScrollLayout.addCategory(D_multiScreenActivity.this,

mInflater, "add cat" + num, R.drawable.icon);

mScrollLayout.snapToScreen(mScrollLayout.getScreenCount() - 1);

mScrollPoints.addPoint(D_multiScreenActivity.this,

mScrollLayout.getScreenCount());

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: