咖啡伴侣

呆在上海
posts - 163, comments - 156, trackbacks - 0, articles - 2

实现第一步,屏蔽默认菜单后:
http://www.blogjava.net/oathleo/archive/2011/11/28/365009.html
接下来就是实现自定义菜单了

先看结果:


就实现了两层,没有考虑多层菜单,菜单项用简单的button实现,感觉还行

主要的代码如下:
        private var titleWindow:Group;
        
private var pointNameGroupMenu:VGroup;
        
private var secondMenu:VGroup;
        
        
public function hiddenPopupMenu():void{
            
if(titleWindow != null){
                PopUpManager.removePopUp(titleWindow);
                pointNameGroupMenu 
= null;
                secondMenu 
= null;
            }
        }
        
private function showPopupMenu(allInterestPointNames:HashSet,physical_x:int,physical_y:int):void {
             
if(allInterestPointNames.size == 1){
                 titleWindow 
= prepareDetailMenu(physical_x,physical_y);
             }
else{
                 titleWindow 
= new Group();   
                 titleWindow.x 
= physical_x;
                 titleWindow.y 
= physical_y;
                 
                 pointNameGroupMenu 
= new VGroup();   
                 pointNameGroupMenu.gap 
= 0;
                 pointNameGroupMenu.horizontalAlign 
= "contentJustify";
                 
                 titleWindow.addElement(pointNameGroupMenu);
                 allInterestPointNames.forEach(function(_node:String):
void{
                     var _point_name:Button 
= new Button();
                     _point_name.label 
= _node;
                     pointNameGroupMenu.addElement(_point_name);
                     _point_name.addEventListener(MouseEvent.MOUSE_OVER,showSecondMenu);
                 });
             }
             PopUpManager.addPopUp(titleWindow, viewer, 
false);   
        }
        
        
private function prepareDetailMenu(_x:int,_y:int):VGroup{
            var detailGroup:VGroup 
= new VGroup();   
            detailGroup.gap 
= 0;
            detailGroup.horizontalAlign 
= "contentJustify";
            detailGroup.x 
= _x;
            detailGroup.y 
= _y;
            
            var _button_point_info:Button 
= new Button();
            _button_point_info.label 
= ResourceUtil.getString("gview_popup_pointinfo");
            detailGroup.addElement(_button_point_info);
            
            var _button_point_trend:Button 
= new Button();
            _button_point_trend.label 
= ResourceUtil.getString("gview_popup_trend");
            detailGroup.addElement(_button_point_trend);
            
            
return detailGroup;
        }
        
        
private function showSecondMenu(evt:MouseEvent):void {
            var _evt_target:Button 
= Button(evt.target);
            var _index:
int = pointNameGroupMenu.getChildIndex(_evt_target);
            
if(secondMenu == null){
                secondMenu 
= prepareDetailMenu(pointNameGroupMenu.measuredWidth,_evt_target.height * _index);
                titleWindow.addElement(secondMenu);
            }
else{
                secondMenu.y 
= _evt_target.height * _index;
            }
        }

posted @ 2011-11-29 16:35 oathleo 阅读(1508) | 评论 (0)编辑 收藏

不要试图改变flash插件自带的右键菜单,没有办法解决
自带的右键菜单坏处大大
1.不能去掉默认的几项(关于)
2.不能实现多层

只能使用js屏蔽掉默认右键事件,然后弹出自己的右键菜单来实现
搜索了半天,找了个可行的方案,实现第一步:
1.屏蔽默认菜单,并响应右键事件

var RightClick = {
    
/**
     *  Constructor
     
*/ 
    init: function () {
        
this.FlashObjectID = "customRightClick";
        
this.FlashContainerID = "flashcontent";
        
this.Cache = this.FlashObjectID;
        
if(window.addEventListener){
             window.addEventListener(
"mousedown"this.onGeckoMouse(), true);
        } 
else {
            document.getElementById(
this.FlashContainerID).onmouseup = function() { document.getElementById(RightClick.FlashContainerID).releaseCapture(); }
            document.oncontextmenu 
= function(){ if(window.event.srcElement.id == RightClick.FlashObjectID) { return false; } else { RightClick.Cache = "nan"; }}
            document.getElementById(
this.FlashContainerID).onmousedown = RightClick.onIEMouse;
        }
    },
    
/**
     * GECKO / WEBKIT event overkill
     * 
@param {Object} eventObject
     
*/
    killEvents: function(eventObject) {
        
if(eventObject) {
            
if (eventObject.stopPropagation) eventObject.stopPropagation();
            
if (eventObject.preventDefault) eventObject.preventDefault();
            
if (eventObject.preventCapture) eventObject.preventCapture();
               
if (eventObject.preventBubble) eventObject.preventBubble();
        }
    },
    
/**
     * GECKO / WEBKIT call right click
     * 
@param {Object} ev
     
*/
    onGeckoMouse: function(ev) {
          
return function(ev) {
        
if (ev.button != 0) {
            RightClick.killEvents(ev);
            
if(ev.target.id == RightClick.FlashObjectID && RightClick.Cache == RightClick.FlashObjectID) {
                RightClick.call();
            }
            RightClick.Cache 
= ev.target.id;
        }
      }
    },
    
/**
     * IE call right click
     * 
@param {Object} ev
     
*/
    onIEMouse: function() {
          
if (event.button > 1) {
            
if(window.event.srcElement.id == RightClick.FlashObjectID && RightClick.Cache == RightClick.FlashObjectID) {
                RightClick.call(); 
            }
            document.getElementById(RightClick.FlashContainerID).setCapture();
            
if(window.event.srcElement.id)
            RightClick.Cache 
= window.event.srcElement.id;
        }
    },
    
/**
     * Main call to Flash External Interface
     * 'flexview_rightClick'
     
*/
    call: function() {
        document.getElementById(
this.FlashObjectID).flexview_rightClick();
    }
}


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
<html>
    
<head>
    
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
<title>TEST</title>
    
    
<script type="text/javascript" src="swfobject.js"></script>
    
<script type="text/javascript" src="rightClick.js"></script>

    
    
</head>
    
<body onload="RightClick.init();">
        
<div id="flashcontent">Flash Player 10 required</div>
        
<script type="text/javascript">
           var so 
= new SWFObject("RightClickAS3.swf""customRightClick""560""420""9""#CCCCCC");
            so.addParam(
"quality""high");
            so.addParam(
"name""customRightClick");
            so.addParam(
"id""customRightClick");
            so.addParam(
"AllowScriptAccess""always");
            so.addParam(
"wmode""opaque");
            so.addParam(
"menu""false");
            so.addVariable(
"variable1""value1");
            so.write(
"flashcontent");
        
</script>
    
</body>
    
</html>
   


package com
{
    
import flash.display.*;
    
import flash.external.ExternalInterface;
    
public class RightClick extends Sprite
    {
        
public function RightClick()
        {
            var methodName:String 
= "flexview_rightClick";
            var method:Function 
= onRightClick;
            ExternalInterface.addCallback(methodName, method);
        }
        
private function onRightClick():void {
            var mx:
int = stage.mouseX;
            var my:
int = stage.mouseY;
            trace(mx 
+ ":" + my);
            
if(my> 0 && my <stage.stageHeight && mx> 0 && mx <stage.stageWidth) {
                
// YOUR CODE HERE
            }
        }
    }
}

posted @ 2011-11-28 17:01 oathleo 阅读(2283) | 评论 (0)编辑 收藏

网上也烂了,自己做 还是浪费一天

教程就不写了,直接写经验

1.平台
flash builder4 + eclipse-jee-galileo (也就是3.5,jee集成了web插件,反正用的不多)

官网下的flash builder4 安装时,选内置的eclipse,死活建不了BlazeDS项目。没心思研究了,以后就按照这个平台来吧。

直接使用这个平台建flex项目,设定server,直接生成,简单

2.AS里
RemoteObject 在sdk里面竟然有2个....
mx.rpc.remoting.RemoteObject api里调用,无法成功
mx.rpc.remoting.mxml.RemoteObject 成功

3.java数组直接amf成 object

4.as的hashset ,拔了个开源的,不错
a3lbmonkeybrain.brainstem.collections

posted @ 2011-11-04 17:05 oathleo 阅读(1843) | 评论 (3)编辑 收藏


当我了解到Flex4那些对我诸多裨益的新特性后, 我便决定转而使用它。刚开始的时候,我试图利用在Flex前作中的认识和既有经验来快速进入状态。但很快我便发现有时即使面对一些显而易见的问题我也不得 不求助于API文档或者运行一些示例程序来弄清这种问题的来龙去脉。根据以往经验,Flex3 的Halo在处理显示列表的时候隐藏了大量的实现细节和不良设计。然而一旦你开始使用新的Spark架构后,你就得以近距离的面对这些实现细节—Halo 究竟在私底下干了什么,而且你会体会到为什么说Spark对于显示列表的处理更为“直白”。

“elements”是一个关键性的问题。elements是何物?它同child是否是一回事?刚开始的时候我曾武断的认为elements不 过是children的另一种说法。通过反复梳理组件中所有的elements和children,我发觉在新的容器类(也包括一些经过改良的传统容器) 某些似乎是理所当然应该具备的方法消失了。如果没有getElements(),我该如何获取elements的数目呢?我能否把 getChildren() 的返回结果作为IVisualElement来对待。这令我十分纠结。

困扰的我于是开始认真阅读学习API文档,Flex的源码以及相关的博客文章。我也曾尝试解读一些博主发布的关于Flex4新特性的幻灯片。然而事实证明脱离讲解而孤立的看幻灯片作用相当有限。

最后,我拼凑了一些言简意赅的示例。这些示例将带领我了解有关elements的全新知识,告诉我那些在新的Spark容器背后发生的故事。

言归正传,首先从问题开始。问题一,“应该如何获得Spark 容器的全部elements?”我曾想当然的认为是通过一个类似Flex3中的getChildren() 的方法。然而实际上我们需要通过两个Property来达到这个目的:numElements & numChildren 。可以通过对numElements计数的循环语句配合getElementAt() 来实现遍历容器elements或特定访问。这种方式还比较直观。问题二,“element和child的区别何在?”,让我们来看看两者的差异。

语义上,element简单的说就是实现了IVisualElement接口的任意型别。child是指扩展了DisplayObject类的任 意型别。判断某个组件是element还是child亦或两者都是的关键在于以下几点。UIComponent(所有Flex组件的基类:译者注)是由 DisplayObject扩展而来,故所有UIComponent都是DisplayObject,也就是说UIComponent都是 children。UIComponent同时也实现了IVisualElement接口,因而所有的UIComponent也可以被作为 elements看待。但这并不是说所有的DisplayObjects(文中所言的DisplayObject一般指扩展于DisplayObject 的子类,译者注)都是elements。容器中的DisplayObject对象是该无疑是容器的child。而只有当此DisplayObject对象 同时也实现了IVisualElement接口时它才是容器的element。那么对容器而言,DisplayObject什么情况下是child,什么 情况下又是element?通过示例来认识这个问题。

在首个示例中,我们使用了传统的Halo容器(这里我们使用的Panel)。Panel扩展与DisplayObject类,所以它可以使用 addChild() 方法。进一步而言,Panel也是Container类的子类(mx.core.Container实现了 IVisualElementContainer接口),它具有addElement() 方法。Container类的IVisualElementContainer接口实现只是基于显示列表API的门面,所以理论上它和同样实现了 IVisualElementContainer接口的新式Spark容器具有相同的方法集合。



于是看起来我们可以任意添加children或element到容器中了。事实却不是这样。并非任意型别的element都能被添加(此处 element泛指实现了IVisualElement接口的类)容器中。视觉元素(VisualElements)和图形元素 (GraphicElements)有一些区别视觉元素(VisualElements)实现了IVisualElement接口,而图形元素 (GraphicElements)实现的是IVisualElement接口的子接口IGraphicElement。IGraphicElement 接口扩展的新特性为容器获取信息提供了额外渠道。某些elements(图形元素是其中之一)无法直接添加至Halo的Panel编译器会告知“这样的对 象需事先包装进一个Group容器中”(实际上错误提示应该是在运行时出现,不关编译器什么事:译者注)。原因马上揭晓。

接下来的示例中,Panel中有若干个UIComponent,其中包括另一个Halo Panel,一个Spark Panel,几个Halo Button和几个Spark Button,以及一个包含有子组件的SkinnableContainer(注意: 包含于SkinnableContainer的组件是只属于SkinnableContainer的children,不是上级容器Panel的 children)。所有组件都继承于DisplayObject,所以它们都是“children”。点击“show children”后可以清楚的了解这一点。进一步而言,所有的组件也都是“element”,因为UIComponent实现了 IVisualElement接口。

看下一个示例。这次我们探讨的容器上Spark Group。与前Halo Panel类似,Group继承于DisplayObjectContainer,它具有addChild() 方法,它同时也实现了IVisualElement接口,所以我们可以用addElement() 方法来IVisualElement对象(elements)。而且Group也接受图形元素(GraphicElements),比如 spark.primitives.Rect。要知道Rect是无法直接添加到Halo Panel中的。Group是怎么做到这一点的?原因就在于Group知道如何使用一种优化的方式来呈现图形元素(GraphicElements)。什 么意思?往下读。

相对于典型的视觉元素(VisualElements),图形元素(GraphicElements)与容器的关系更为紧密。其关键在于 IGraphicElement接口。上面曾经提到,这个扩展于IVisualElement的接口(此即图形元素(GraphicElements)可 以通过Group的addElement() 方法来添加至其上的原因所在)。然而由于图形元素(GraphicElements)不是DisplayObject,所以他们在被“投映”到某个作为他 父对象的DisplayObject前是无法被显示出来的。基于这个原因,当添加一个“Rectangle”到Group时,需要有 DisplayObject来绘制这个Rectangle。更有效率一点的做法是Group尽可能的复用同一个DisplayObject来绘制多个图形 元素(GraphicElements)。容器可以使用任何实现了ISharedDisplayObject接口的DisplayObject来绘制图形 元素(GraphicElements)。第一个示例中的Halo Panel无法使用这种方式来绘制图形元素(GraphicElements),编译器会报错:“必须将其包装至一个合适的容器中”。而Group支持这 种优化方式,所以能添加图形元素(GraphicElements)。

另外需要注意的一点是,有些图形元素(GraphicElements)的绘制由Group提供DisplayObject来完成,也有的是自行 创建专属的DisplayObject来完成绘制。IGraphicElement接口甚至允许把对象自己创建的DisplayObject交由容器管理 (换而言之就是以child形态添加的DisplayObject会以IGraphicElement的面貌来绘制自己)。

这意味着什么?这意味着在接下来的示例中,children的数目和elements的数目是不一样的。这个示例使用了与第一个示例相同的组件集 合外,还增加了4个矩形图形元素(GraphicElements)。所有子对象皆为IVisualElement,但不是都可以称为children。 几个矩形是图形元素(GraphicElements),它们并不继承于DisplayObject。Group不在乎这点,它知道添加 DisplayObject来绘制这些图形元素(GraphicElements)。由于几个矩形的尺寸和角度有所不同,所以Group会创建2个新的 DisplayObject来绘制这4个矩形。很酷吧!



现在来看示例三。我们用一个SkinnableContainer替换先前的Group。SkinnableContainer有和先前相同的子 组件集,它还能利用Skin来增强视觉效果。Skin是SkinnableContainer唯一的child。SkinnableContainer的 默认Skin类由一个矩形和一个被称为ContentGroup的Group组成。该Group的作用在于规划出容器内组件的添加位置。

这个示例证明了这样的事实,即使SkinnableContainer拥有10个elements,但它只有唯一的child:它自己的 Skin。而且这个Skin也只有唯一的child:名为ContentGroup的Group组件。你也许会感到奇怪:为什么Skin的 children不是2个:其一是ContentGroup,另一个是用于绘制作为边框的Rectangle的DisplayObject?这是因为 Skin类继承自Group类,而Group只在它确实需要绘制其包容的图形元素(GraphicElements)时才会添加 DisplayObject,目前的情况下不需要。Skin类具备直接在其上绘制Rect图形元素(GraphicElements)的能力,这归功于 Skin类的上级类Group实现了ISharedDisplayObject接口。这意味着它在需要时能作为共享的DisplayObject来绘制图 形元素(GraphicElements)。Skin负责管理用于呈现图形元素(GraphicElements)的DisplayObject,在当前 示例中,Skin自己就是用于绘制的DisplayObject!如果你的自定义Skin中有其它的Rectangle,并将该Skin赋予 SkinnableContainer,这种情况下Skin会判断是否需要更多的DisplayObject来绘制额外的Rectangle。这时你可能 会发现在Skin的children列表中有更多的child。

值得注意的是,示例中SkinnableContainer,它的Skin以及Skin的ContentGroup这三者的element列表的 数目是相同的。通过SkinnableContainer的源码可以知道,numElement的值实际上来源于与之对应的 CurrentContentGroup的numElement。所以基本上对SkinnableContainer的elements的检索是被重定向 到它的ContentGroup上的。SkinnableContainer的Skin也有类似行为。它继承于Group,Group的 numElement的值取自其内部的mxmlContent属性。该属性是一个保存了Group可视内容children的数组。这两个属性与 Panel的RawChildren属性十分相似,它用于返回Panel上的所有children而不是getChildren()方法返回的仅仅你添加 到Panel上的那些。



通过以上阅读,也许起不到拨云见日的效果。但可以让你明白厘清以下七个类/接口的继承结构和相互关系是十分有必要的:
1. DisplayObject
2. UIComponent
3. Container
4. IVisualElement
5. IGraphicElement
6. IVisualElementContainer
7. ISharedDisplayObject

一旦你掌握它们之间的关系,你就能明白elements 和children的不同。可以肯定的是我在某些问题的认识和阐述上存在很多谬误之处。如果你发现了这样的问题望不吝赐教,在评论处写下您的正确观点吧。

posted @ 2011-10-14 11:05 oathleo 阅读(812) | 评论 (0)编辑 收藏

请保留:
http://www.blogjava.net/oathleo/archive/2011/09/23/android_Fruit_Ninja.html


android手势加上了,比如左右滑动
但是用户经常不能感受到是否滑动了,
水果忍者刀锋效果/光刀效果就相当不错

网上搜了下,大多是ios的实现,想想原理可能不是很复杂,就实现了个最简单的。
原理
1.在背景view上再加一层view专门负责draw刀锋
2.刀锋就是随着手势move,动态画shape
3.接受到事件得dispatchTouchEvent,否则下面的组件无法获得事件了
4.下面的组件事件等无需更改,互不耦合
5.一个类实现,不涉及其他第三方
6.只实现了一个最简单的形状,水果忍者里面实现了很多复杂形状,可以在这个基础上进行扩展
效果如图



代码:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;



/**
 * 
 * 模仿水果忍者刀锋效果
 * 
@author leooath@gmail.com
 *
 
*/
public class GestureView extends View {

    
private Paint paint;

    
private float startX = Float.NaN;
    
private float startY = Float.NaN;
    
private float endX = Float.NaN;
    
private float endY = Float.NaN;

    
//下层view
    private View viewer;
    
private static final int gestureColor = Color.rgb(153153153);
    
private static final int alpha = 220;
    
private static final int alpha_full = 255;
    
//刀锋长度
    private static final int shape_length = 40;
    
//刀锋截短时间
    private static final int shape_cut_time = 150;
    
    
public GestureView(Context context, View viewer) {
        
super(context);
        
this.viewer = viewer;
        paint 
= new Paint();
        paint.setStyle(Paint.Style.FILL);
    }

    
public void draw(Canvas canvas) {
        
super.draw(canvas);
        
if (!Float.isNaN(startX) && !Float.isNaN(endY)) {
            
float gap = ViewUtils.getGap(startX, startY, endX, endY);
            
float w = gap / 10;
            
//背景shape外侧点高度
            float h = w > 7 ? 7 : w;
            
//填充shape外侧点高度
            float h2 = h * 2 / 3

            
double length = Math.pow(Math.pow(w, 2+ Math.pow((h), 2), 0.5);
            
double length2 = Math.pow(Math.pow(w, 2+ Math.pow((h2), 2), 0.5);
            
            
double ang1_1 = Math.atan((endY - startY) / (endX - startX));
            
double ang1_2 = Math.atan(h / w);
            
double angle1_1 = ang1_1 + ang1_2;
            
double angle1_2 = ang1_1 - ang1_2;
            
            
double ang2_2 = Math.atan(h2 / w);
            
double angle2_1 = ang1_1 + ang2_2;
            
double angle2_2 = ang1_1 - ang2_2;
            
if (endX > startX) {
                
float xx1 = endX - (float) (length * Math.cos(angle1_1));
                
float yy1 = endY - (float) (length * Math.sin(angle1_1));
                
float xx2 = endX - (float) (length * Math.cos(angle1_2));
                
float yy2 = endY - (float) (length * Math.sin(angle1_2));

                
float xx12 = endX - (float) (length2 * Math.cos(angle2_1));
                
float yy12 = endY - (float) (length2 * Math.sin(angle2_1));
                
float xx22 = endX - (float) (length2 * Math.cos(angle2_2));
                
float yy22 = endY - (float) (length2 * Math.sin(angle2_2));
                
                Path backPath 
= new Path();
                backPath.moveTo(startX, startY);
                backPath.lineTo(xx1, yy1);
                backPath.lineTo(endX, endY);
                backPath.lineTo(xx2, yy2);
                backPath.close();
                
                Path fillPath 
= new Path();
                fillPath.moveTo(startX, startY);
                fillPath.lineTo(xx12, yy12);
                fillPath.lineTo(endX, endY);
                fillPath.lineTo(xx22, yy22);
                fillPath.close();

                paint.setColor(gestureColor);
                paint.setAlpha(alpha);
                canvas.drawPath(backPath, paint);
                
                paint.setColor(Color.WHITE);
                paint.setAlpha(alpha_full);
                canvas.drawPath(fillPath, paint);
            } 
else {
                
float xx1 = endX + (float) (length * Math.cos(angle1_1));
                
float yy1 = endY + (float) (length * Math.sin(angle1_1));
                
float xx2 = endX + (float) (length * Math.cos(angle1_2));
                
float yy2 = endY + (float) (length * Math.sin(angle1_2));

                
float xx12 = endX + (float) (length2 * Math.cos(angle2_1));
                
float yy12 = endY + (float) (length2 * Math.sin(angle2_1));
                
float xx22 = endX + (float) (length2 * Math.cos(angle2_2));
                
float yy22 = endY + (float) (length2 * Math.sin(angle2_2));
                
                Path backPath 
= new Path();
                backPath.moveTo(startX, startY);
                backPath.lineTo(xx1, yy1);
                backPath.lineTo(endX, endY);
                backPath.lineTo(xx2, yy2);
                backPath.close();

                Path fillPath 
= new Path();
                fillPath.moveTo(startX, startY);
                fillPath.lineTo(xx12, yy12);
                fillPath.lineTo(endX, endY);
                fillPath.lineTo(xx22, yy22);
                fillPath.close();

                paint.setColor(gestureColor);
                paint.setAlpha(alpha);
                canvas.drawPath(backPath, paint);
                
                paint.setColor(Color.WHITE);
                paint.setAlpha(alpha_full);
                canvas.drawPath(fillPath, paint);
            }
        }
    }

    
public boolean onTouchEvent(android.view.MotionEvent event) {
        
if(event.getPointerCount() == 1){
            
int action = event.getAction();
            
if (MotionEvent.ACTION_DOWN == action) {
                startX 
= event.getX();
                startY 
= event.getY();
            } 
else if (MotionEvent.ACTION_MOVE == action) {
                endX 
= event.getX();
                endY 
= event.getY();
                
                
//刀锋截短时间,则截短至一半
                if ((event.getEventTime() - event.getDownTime()) > shape_cut_time) {
                    
if(Math.abs(endX - startX) > shape_length && Math.abs(endY - startY) > shape_length){
                        startX 
= (float) (startX + (endX - startX) * 0.5);
                        startY 
= (float) (startY + (endY - startY) * 0.5);
                    }
                }

                invalidate();
            } 
else if (MotionEvent.ACTION_UP == action) {
                startX 
= Float.NaN;
                startY 
= Float.NaN;
                endX 
= Float.NaN;
                endY 
= Float.NaN;
                invalidate();
            }
        }
        
//该view消费了event,所以下层的view必须dispatchTouchEvent才能获得事件
        MotionEvent newEvent = MotionEvent.obtain(event);
        viewer.dispatchTouchEvent(newEvent);
        
return true;
    }

}

posted @ 2011-09-23 11:29 oathleo 阅读(3935) | 评论 (5)编辑 收藏

对于View来说,事件的返回值是关注的,down时返回true,才能接受up的事件
对于SurfaceView,事件返回值貌似没有什么作用

        setOnTouchListener(new OnTouchListener() {
            
public boolean onTouch(View v, MotionEvent event) {
                System.out.println(
"touch");
                
return true;
            }
        });

有兴趣的朋友可以试试上面的代码

posted @ 2011-09-19 16:31 oathleo 阅读(1549) | 评论 (0)编辑 收藏

对于工业生产现场来说,过程实时数据变化很快,数据存储量很大,如果每个数据都存储,在经历不长时间后就会占据大量磁盘空间。一般来说,工业生产的很多数 据是线性变化的,或者是符合某种规律变化的,如果数据库能够根据某些条件进行判断,将某些可忽略的数据,不进行存储,而当需要查找该数据时,可以通过线性 或步进插值计算出来,就可以大幅度提高存储效率,同时节约磁盘空间。

    上述描述的情况就是在线数据压缩。所谓数据压缩,就是丢弃那些对于在准确重现现场设备(以下称为测点)历史曲线时不是必需的测点数据。

    当今,非常流行的数据压缩算法是由美国OSI软件公司研发的旋转门压缩算法,此算法已经成功地运用在了PI实时数据库系统当中,此算法主要针对的对象是浮点数数据类型的数据。

    旋转门压缩算法分析:

  • 部分原文:

    With the swinging door algorithm, a value is stored if a straight line drawn between the last stored value and the next value does not come within the compression deviation specification of all the intermediate points. Two slopes are required to carry out this test. The following figure shows the slopes as they are initialized after a value is stored:

在线数据压缩算法分析

 

Figure1 – Swinging Door slopes after recording a value

    The dotted lines are the two slopes. Let the compression deviation specification be 8. One of the lines is drawn from the last recorded value plus 8 through whichever value maximizes the slope of the line. This is the top dotted line in Figure 1. The other dotted line is drawn from the last recorded value minus 8 through whichever value minimizes the slope of the line. The third line is drawn between the last recorded value and the new value. This is the solid line in Figure 1. The previous value is recorded if the slope of the top dotted line is greater than the slope of the solid line or the slope of the solid line is greater than the slope of the bottom dotted line.

    The algorithm ensures that each discarded value falls within the compression deviation specification of the solid line. The compression deviation specification is also the maximum error in a trend of archived values. The next figure shows the lines after four more values have been received.

    The next figure shows the arrival of a value which causes the previous value to be recorded.

在线数据压缩算法分析

 

Figure 2 – Recording a new value

  • 中文解释:

    对于旋转门压缩算法来说,先由上一保存数据项和当前数据项来画出一条直线(在二维坐标图上),如果待保存数据项不在当前数据项和上一保存数据项的压缩偏差范围之内,则待保存数据项被保存。实验中还需要两条斜线(旋转门)。图1(Figure 1)中显示了这两个旋转门,传入系统的第一个测点数据项会直接被保存,否则因为数据库中没有被保存的测点数据项就无法确定旋转门了。

    压缩偏差是旋转门压缩算法中的重要参数,它是人为设定的绝对误差值,可以简单的理解为在绝对误差范围内,数据被压缩掉,在绝对误差范围外,数据不被压缩。

    另外,算法的实现还需要计算以下几个斜率:

   (1)上斜率 K1 =(当前数据项数值 -(上一保存数据项数值 - 压缩偏差))/(当前数据项时间 - 上一保存数据项时间)

   (2)下斜率 K2 =(当前数据项数值 -(上一保存数据项数值 + 压缩偏差))/(当前数据项时间 - 上一保存数据项时间)

   (3)中间斜率K =(当前数据项数值 - 待保存数据项数值)/(当前数据项时间 - 待保存数据项时间)

    通过计算压缩变量上一保存数据项和当前数据项与待保存数据项的斜率来进行压缩控制。即:

    如果 K2KK1,待保存数据项被压缩。

    如果 K<K2或者K>K1,待保存数据项被存储。

 

算法实现流程如下:

1.第一个数据项处理:直接存入数据库。

2.第二个数据项处理:计算前后两数据项的上下两个斜率,并将上下斜率作为后续判断的依据。

3.两个数据项以上处理:计算上中下斜率,进行判断:(1)如果没有通过旋转门压缩检测,把上一个数据项信息保存,并将新的上下斜率保存作为后续判断的依据;(2)如果通过旋转门压缩检测,则不需要保存。

4.循环执行第三步中的压缩条件判断。




#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
static int maxnum = 3600;
void main(int argc,char **argv[])
{
  int now=0, start=0; 
  FILE *fd, *fd1;
 
  fd = fopen("test", "r");
  fd1 = fopen("test.zip", "w");
 
  float E=10.01;
  float mem, mem_old;
  float upgate; /*定义上门*/ 
  float downgate; /*定义下门*/ 
  float k1; /*k1表示上门和过程数据间的斜率*/ 
  float k2; /*k2表示下门和过程数据间的斜率*/ 
 
  fread(&mem, sizeof(float), 1, fd);
  mem_old = mem;
 
  for(;;) {
   if(now == maxnum-1) {
       fwrite(&mem, sizeof(float), 1, fd1);
       break;
    }
   fwrite(&mem, sizeof(float), 1, fd1);
    start = now;
    upgate=mem+E; 
    downgate=mem-E; 
    k1=-10000; 
    k2=-10000; 
    for(;;) {
     now++;
     mem_old = mem;
     fread(&mem, sizeof(float), 1, fd);
     if(fabs(mem-upgate)>0.001){
      if((mem-upgate)/(now -start)>k1) k1=(mem-upgate)/(now-start); 
       else {
        now=now++;
        fwrite(&mem_old, sizeof(float), 1, fd1);
        break;
       }
      }
      if(fabs(mem-downgate)>0.001){
        if((downgate-mem)/(now-start)>k2) k2=(downgate-mem)/(now-start); 
       else {
        now=now++;
        fwrite(&mem_old, sizeof(float), 1, fd1);
        break;
       }     
      } 
   if(now == maxnum-1) {
        break;
      }
    }

posted @ 2011-09-14 13:46 oathleo 阅读(5452) | 评论 (0)编辑 收藏

http://cnbeta.com/articles/154387.htm



世上最伟大的十个公式,薛定谔方程排名第六,质能方程排名第五

leoliyuan发布于 2011-09-08 08:49:56|4126 次阅读 字体: 打印预览 分享至新浪微博 转贴到开心网 分享到校内人人网 添加到Google书签

cnBeta 科学探索

英国科学期刊《物理世界》曾让读者投票评选了“最伟大的公式”,最终榜上有名的十个公式既有无人不知的1+1=2,又有著名的E=mc2;既有简单的-圆周公式,又有复杂的欧拉公式……

从什么时候起我们开始厌恶数学?这些东西原本如此美丽,如此精妙。这个地球上有多少伟大的智慧曾耗尽一生,才最终写下一个等号。每当你解不开方程的时候,不妨换一个角度想,暂且放下对理科的厌恶和对考试的痛恨。因为你正在见证的,是科学的美丽与人类的尊严。

No.10 圆的周长公式(The Length of the Circumference of a Circle)

 

 

这公式贼牛逼了,初中学到现在。目前,人类已经能得到圆周率的2061亿位精度。还是挺无聊的。现代科技领域使用的-圆周率值,有十几位已经足够了。如果用 35位精度的-圆周率值,来计算一个能把太阳系包起来的一个圆的周长,误差还不到质子直径的百万分之一。现在的人计算圆周率,多数是为了验证计算机的计算 能力,还有就是为了兴趣。

 

No.9 傅立叶变换(The Fourier Transform)

 

 

这个挺专业的,一般人完全不明白。不多作解释。简要地说没有这个式子没有今天的电子计算机,所以你能在这里上网除了感谢党感谢政府还要感谢这个完全看不懂的式子。另外傅立叶虽然姓傅,但是法国人。

 

No.8 德布罗意方程组(The de Broglie Relations)

 

 

这个东西也挺牛逼的,高中物理学到光学的话很多概念跟它是远亲。简要地说德布罗意这人觉得电子不仅是一个粒子,也是一种波,它还有 “波长”。于是搞啊搞就有了这个物质波方程,表达了波长、能量等等之间的关系。同时他获得了1929年诺贝尔物理学奖。

 

No.7 1+1=2

这个公式不需要名称,不需要翻译,不需要解释。

 

No.6 薛定谔方程(The Schr&ouml;dinger Equation)


 

也是一般人完全不明白的。因此我摘录官方评价:“薛定谔方程是世界原子物理学文献中应用最广泛、影响最大的公式。”由于对量子力学的杰出贡献,薛定谔获得1933年诺贝尔物理奖。

另外薛定谔虽然姓薛,但是奥地利人。

 

No.5 质能方程(Mass–energy Equivalence)

 

 

好像从来没有一个科学界的公式有如此广泛的意义。在物理学“奇迹年”1905年,由一个叫做爱因斯坦的年轻人提出。同年他还发表了《论动体的电动力学》——俗称狭义相对论。

这个公式告诉我们,爱因斯坦是牛逼的,能量和质量是可以互换的。副产品:原子弹。

 

No.4 勾股定理/毕达哥拉斯定理(Pythagorean Theorem)

 

 

做数学不可能没用到过吧,不多讲了。

 

No.3 牛顿第二定律(Newton's Second Law of Motion)

 

 

有史以来最伟大的没有之一的科学家在有史以来最伟大没有之一的科学巨作《自然哲学的数学原理》当中的被认为是经典物理学中最伟大的没有之一的核心定律。动力的所有基本方程都可由它通过微积分推导出来。对于学过高中物理的人,没什么好多讲了。

 

No.2 欧拉公式(Euler's Identity)

 

 

这 个公式是上帝写的么?到了最后几名,创造者个个神人。欧拉是历史上最多产的数学家,也是各领域(包含数学的所有分支及力学、光学、音响学、水利、天文、化 学、医药等)最多著作的学者。数学史上称十八世纪为“欧拉时代”。欧拉出生于瑞士,31岁丧失了右眼的视力,59岁双眼失明,但他性格乐观,有惊人的记忆 力及集中力。他一生谦逊,很少用自己的名字给他发现的东西命名。不过还是命名了一个最重要的一个常数——e。

关 于e,以前有一个笑话说:在一家精神病院里,有个病患整天对着别人说,“我微分你、我微分你。”也不知为什么,这些病患都有一点简单的微积分概念,总以为 有一天自己会像一般多项式函数般,被微分到变成零而消失,因此对他避之不及,然而某天他却遇上了一个不为所动的人,他很意外,而这个人淡淡地对他说,“我 是e的x次方。”

这个公式的巧妙之处在于,它没有任何多余的内容,将数学中最基本的e、i、pie放在了同一个式子中,同时加入了数学也是哲学中最重要的0和1,再以简单的加号相连。

高斯曾经说:“一个人第一次看到这个公式而不感到它的魅力,他不可能成为数学家。”

 

No.1 麦克斯韦方程组(The Maxwell's Equations)

积分形式:

 

微分形式:

 

任何一个能把这几个公式看懂的人,一定会感到背后有凉风——如果没有上帝,怎么解释如此完美的方程?这组公式融合了电的高斯定律、磁的高斯定律、法拉第定律 以及安培定律。比较谦虚的评价是:“一般地,宇宙间任何的电磁现象,皆可由此方程组解释。”到后来麦克斯韦仅靠纸笔演算,就从这组公式预言了电磁波的存 在。我们不是总喜欢编一些故事,比如爱因斯坦小时候因为某一刺激从而走上了发奋学习、报效祖国的道路么?事实上,这个刺激就是你看到的这个方程组。也正是 因为这个方程组完美统一了整个电磁场,让爱因斯坦始终想要以同样的方式统一引力场,并将宏观与微观的两种力放在同一组式子中:即著名的“大一统理论”。爱 因斯坦直到去世都没有走出这个隧道,而如果一旦走出去,我们将会在隧道另一头看到上帝本人。

posted @ 2011-09-08 09:22 oathleo 阅读(2312) | 评论 (3)编辑 收藏

        <activity android:name=".LoginActivity" android:label="@string/app_name" android:launchMode="singleTask">

launchmode4种模式:
1,standard:
如果从A跳到A,intent5次,task里5个activity;
2,single Top:
如果从A 跳B,再从B跳A,如果此时栈顶为A,则不创建新实例,直接把Intent给A,但如果栈顶不是A,则还要创建A的实例
3,singleTask
如果从A跳B,再从B跳A,无论是否栈顶栈底,只要A在,则将Intent给A,不会创建A的新实例;
4,singleInstance
不同于前3种模式,前3种只是在同一个task的,而实例化的策略不同。这种模式下的activity会单独存在一个task下。
现成的例子是google地图。比如我有一个应用是导游方面的,其中调用的google地图Activity。那么现在我比如按home(后台 activity onstop,back是finish)键,然后到应用列表中打开google地图,你会发现显示的就是刚才的地图,实际上是同一个Activity。
如果使用上面三种模式,是无法实现这个需求的。google地图应用中有多个上下文Activity,比如路线查询等的,导游应用也有一些上下文Activity。在各自应用中回退要回退到各自的上下文Activity中。
总结:
1 2:会创建新实例
3 4:不会创建新实例
123:activity的taskid相同
4:activity的taskid不同。被分到单独一个task中

posted @ 2011-09-02 13:11 oathleo 阅读(302) | 评论 (0)编辑 收藏

    popupWindow.setWidth(LayoutParams.WRAP_CONTENT);               
    popupWindow.setHeight(LayoutParams.WRAP_CONTENT);         
    

view自适应
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                LinearLayout linearLayout 
= new LinearLayout(c);
                linearLayout.setLayoutParams(params);


使用:
  mPop.showAtLocation((View) v.getParent(), Gravity.TOP | Gravity.LEFT, 25250);

以上面一句为例:第一个参数是指PopupWindow显示在哪一个View之上.后面三个参数控制PopupWindow显示的位置,此处表明PopupWindow显示在距左上角x252个像素,y50个像素.

posted @ 2011-09-02 11:23 oathleo 阅读(4573) | 评论 (0)编辑 收藏

仅列出标题
共17页: First 上一页 3 4 5 6 7 8 9 10 11 下一页 Last