解决方案 »
- Activity中停止服务报错,请大侠指点。。。
- android绘图问题,指定填充一个区域颜色
- 哪位高手过来帮我看看
- 菜鸟请教关于http连接时 设置进度条的问题
- 怎么查看widget的源码?
- 调用android的Camera 执行结果没有回调onActivityResult()
- Android 打开应用
- activity背景图占用内存太大怎么优化
- android TimePickerDialog 的问题
- android 蓝牙ble 连接超时,有懂得的高手帮忙下,谢谢了。
- 需求:在自己的程序中调用联系人列表,然后选择某个联系人,返回该联系人的Uri
- USB调试模式_eclipse_logCat看不到日志信息
package com.yfmandroid.widget;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LayoutAnimationController;
import android.view.animation.ScaleAnimation;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.ScrollView;public abstract class FixedGrid extends LinearLayout {
private static final String LOG_TAG = "FixedGrid";
protected Context mContext;
private LinearLayout mGridHeaderLayout;
private LinearLayout mColumnHeaderLayout;
private LinearLayout mRowHeaderLayout;
private LinearLayout mContentLayout; private LinearLayout mUpLayout; private LinearLayout mDownLayout; private HorizontalScrollView mColumnHeaderScroll; private ScrollView mRowHeaderScroll; private CustomScrollView mContentScroll;
private FixedGridMultiPointTouchListener mOnTouchListener;
private boolean mScalable;
public FixedGrid(Context context) {
this(context, false);
} public FixedGrid(Context context, boolean scalable) {
super(context);
mContext = context;
mScalable = scalable;
initGrid();
mOnTouchListener = new FixedGridMultiPointTouchListener();
setOnTouchListener(mOnTouchListener);
mContentScroll.setOnTouchListener(mOnTouchListener);
} private void initGrid() {
setOrientation(VERTICAL);
setBackgroundColor(Color.BLACK); mUpLayout = new LinearLayout(mContext);
mUpLayout.setBackgroundColor(Color.BLACK);
mUpLayout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
addView(mUpLayout); mDownLayout = new LinearLayout(mContext);
mDownLayout.setBackgroundColor(Color.BLACK);
mDownLayout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT));
addView(mDownLayout); addGridHeader();
addColumnHeader();
addRowHeader();
addContent();
} private void addGridHeader() {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(1, 1, 1, 1);
mGridHeaderLayout = genGridHeader();
mGridHeaderLayout.setLayoutParams(layoutParams);
mUpLayout.addView(mGridHeaderLayout);
} private void addColumnHeader() {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(1, 1, 1, 1);
mColumnHeaderScroll = new HorizontalScrollView(mContext) {
public boolean onTouchEvent(MotionEvent ev) {
return false;
};
};
mColumnHeaderScroll.setLayoutParams(layoutParams);
mColumnHeaderScroll.setHorizontalScrollBarEnabled(false);
mColumnHeaderScroll.setHorizontalFadingEdgeEnabled(false);
mColumnHeaderLayout = genColumnHeader();
mColumnHeaderScroll.addView(mColumnHeaderLayout);
mUpLayout.addView(mColumnHeaderScroll);
} private void addRowHeader() {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.FILL_PARENT);
layoutParams.setMargins(1, 1, 1, 1);
mRowHeaderScroll = new ScrollView(mContext) {
public boolean onTouchEvent(MotionEvent ev) {
return false;
};
};
mRowHeaderScroll.setLayoutParams(layoutParams);
mRowHeaderScroll.setVerticalScrollBarEnabled(false);
mRowHeaderScroll.setVerticalFadingEdgeEnabled(false);
mRowHeaderLayout = genRowHeader();
mRowHeaderScroll.addView(mRowHeaderLayout);
mDownLayout.addView(mRowHeaderScroll);
} private void addContent() {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
layoutParams.setMargins(1, 1, 1, 1);
mContentScroll = new CustomScrollView(mContext) {
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
mRowHeaderScroll.scrollTo(0, y);
mColumnHeaderScroll.scrollTo(x, 0);
}; public void fling(int velocityX, int velocityY) {
super.fling(velocityX, velocityY);
mRowHeaderScroll.fling(velocityY);
mColumnHeaderScroll.fling(velocityX);
};
};
mContentScroll.setFlingEnabled(false);
mContentScroll.setLayoutParams(layoutParams);
mContentLayout = genContent();
mContentScroll.addView(mContentLayout);
mDownLayout.addView(mContentScroll);
} protected abstract LinearLayout genGridHeader(); protected abstract LinearLayout genColumnHeader(); protected abstract LinearLayout genRowHeader(); protected abstract LinearLayout genContent(); @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.e(LOG_TAG, "rowwidth: " + mRowHeaderScroll.getWidth());
}
private class FixedGridMultiPointTouchListener extends MultiPointTouchListener{ @Override
public boolean onTouch(View v, MotionEvent event) {
if(!super.onTouch(v, event)){
return mContentScroll.onTouchEvent(event);
}
return true;
}
@Override
protected boolean onScale(float oldScale, float lastScale, float newScale, final float clearScale, float midX, float midY){
if(!mScalable){
return false;
}
Log.e(LOG_TAG, "onScale: " + oldScale + ", " + lastScale + ", " + newScale + ", " + clearScale + ", " + midX + ", " + midY);
ScaleAnimation animation = new ScaleAnimation(lastScale, newScale, lastScale, newScale);
//Log.e(LOG_TAG, animation + " ==== scaling: " + lastScale + "==>" + newScale);
animation.setAnimationListener(new ScaleAnimation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
// printSize(FixedGrid.this, "gird");
// printSize(mRowHeaderScroll, "rows");
// printSize(mRowHeaderLayout, "rowl");
// FixedGrid.this.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.FILL_PARENT));
}
private void printSize(View v, String tag){
Log.e(LOG_TAG, tag + ": " + v.getWidth() + ", " + v.getHeight());
}
});
animation.setFillAfter(true);
animation.setDuration(1);
// startAnimation(animation);
LayoutAnimationController controller = new LayoutAnimationController(animation);
// if(newScale < 1){
// //setLayoutParams(new LinearLayout.LayoutParams((int)(800 / newScale), (int)(535 / newScale)));
// }else{
// //setLayoutParams(new LinearLayout.LayoutParams(800, (int)(535 / newScale)));
// }
setLayoutAnimation(controller);
animation.reset();
clearAnimation();
invalidate();
return true;
}
}
}
package com.yfmandroid.widget;import android.graphics.PointF;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;public class MultiPointTouchListener implements OnTouchListener {
private static final String LOG_TAG = "MultiPointTouchListener"; private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE; private PointF start = new PointF();
private PointF mid = new PointF();
private float oldDist = 1f;
private float mLastDist;
private float mOldScale = 1;
private float mLastScale;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
mLastDist = oldDist;
if (oldDist > 10f) {
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (mode == ZOOM) {
mOldScale = mLastScale;
}
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
return onMove(event.getX() - start.x, event.getY() - start.y);
} else if (mode == ZOOM) {
// Log.e(LOG_TAG, "zooming");
float lastDist = spacing(event);
// Log.e(LOG_TAG, "oldDist: " + oldDist);
// Log.e(LOG_TAG, "lastDist: " + lastDist);
if (lastDist > 10f) {
float lastScale = mLastScale;
mLastScale = lastDist / oldDist * mOldScale;
// Log.e(LOG_TAG, "lastScale: " + lastScale);
// Log.e(LOG_TAG, "mLastScale: " + mLastScale);
float clearScale = lastDist / mLastDist;
mLastDist = lastDist;
// Log.e(LOG_TAG, "scalexxx: " + (mLastScale - lastScale));
if(Math.abs(mLastScale - lastScale) > 0.001){
return onScale(mOldScale, lastScale, mLastScale, clearScale, mid.x, mid.y);
}
return true;
}
}
break;
} return false;
}
protected boolean onMove(float x, float y){
return false;
}
protected boolean onScale(float oldScale, float lastScale, float newScale, float clearScale, float midX, float midY){
return false;
} protected void dumpEvent(MotionEvent event) {
String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
Log.e(LOG_TAG, sb.toString());
} /** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
} /** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
}
需要缩放时直接重画屏幕好了。