ITKeyword,专注技术干货聚合推荐

注册 | 登录

[置顶] java 接口interface的使用

fhy_2008 分享于 2011-10-14

2019阿里云全部产品优惠券(新购或升级都可以使用,强烈推荐)
领取地址https://promotion.aliyun.com/ntms/yunparter/invite.html

首先:创建一个接口类, 里面只有一个空方法,没有方法体:

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 points = new ArrayList();
?? ?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 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 categories) {
?? ??? ?this.categories = categories;
?? ?}

?? ?public void initScreen(Activity activity, LayoutInflater inflater) {
?? ??? ?if (categories == null) {
?? ??? ??? ?return;
?? ??? ?}

?? ??? ?Set<>> entrySet = categories.entrySet();
?? ??? ?int i = 0;
?? ??? ?int totalScreenNum = categories.size() / CATEGORY_COUNT_PER_SCREEN;
?? ??? ?int currentScreen = 0;
?? ??? ?Map oneScreenCategories = null;
?? ??? ?for (Iterator<>> 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();
?? ??? ??? ?}

?? ??? ??? ?// create map for last category screen
?? ??? ??? ?if (currentScreen > totalScreenNum + 1) {
?? ??? ??? ??? ?oneScreenCategories = new LinkedHashMap();
?? ??? ??? ?}

?? ??? ??? ?// put every 9 category objects into one map
?? ??? ??? ?Map.Entry entry = (Entry) 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 categories = new LinkedHashMap();
?? ??? ??? ?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 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();
?? ??? ?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());
?? ?}
}

首先:创建一个接口类, 里面只有一个空方法,没有方法体: package com.lp.scroll; public interface SelectPoint{ ?? ?public void changeSelectedPoint(int position); } 然后,在实现改接口

相关阅读排行


用户评论

游客

相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。