当前位置:  编程技术>移动开发
本页文章导读:
    ▪onTouchEvent跟onInterceptTouchEvent详细研究        onTouchEvent和onInterceptTouchEvent详细研究 面试的时候曾被问过这两个方法的调用顺序,当时也只是知道onInterceptTouchEvent在前,具体的执行过程,相互的影响却不知道.今天写了一个小demo详细研究了一.........
    ▪ getWidth()替0        getWidth()为0 一般在刚开始开发android时,会犯一个错误,即在View的构造函数中获取getWidth()和getHeight(),当一个view对象创建时,android并不知道其大小,所以getWidth()和getHeight()返回的结果是0.........
    ▪ java解压rar资料       java解压rar文件 import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.regex.Matcher;import java.util.regex.Pattern; import de.innosystec.unrar.Archive;import de.innosystec.unrar.........

[1]onTouchEvent跟onInterceptTouchEvent详细研究
    来源: 互联网  发布时间: 2014-02-18
onTouchEvent和onInterceptTouchEvent详细研究

面试的时候曾被问过这两个方法的调用顺序,当时也只是知道onInterceptTouchEvent在前,具体的执行过程,相互的影响却不知道.今天写了一个小demo详细研究了一下这两个方法之间的关系.

首先上代码:

主activity:InterceptTouchStudyActivity

 

package com.touchstudy;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class InterceptTouchStudyActivity extends Activity {

    TextView tv;

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

    }

}

 布局文件main.xml

 

<?xml version="1.0" encoding="utf-8"?>
<com.touchstudy.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.touchstudy.LayoutView2
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:orientation="vertical" >

        <com.touchstudy.MyTextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FFFFFF"
            android:text="AB"
            android:textColor="#0000FF"
            android:textSize="40sp"
            android:text />
    </com.touchstudy.LayoutView2>

</com.touchstudy.LayoutView1>

 类LayoutView1

 

package com.touchstudy;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class LayoutView1 extends LinearLayout {

    private final String TAG = "LayoutView1";

    public LayoutView1(Context context, AttributeSet attrs) {

        super(context, attrs);

        Log.d(TAG, TAG);

    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        switch (action) {

            case MotionEvent.ACTION_DOWN:

                Log.d(TAG, "onInterceptTouchEvent1 action:ACTION_DOWN");

                // return true;

                break;

            case MotionEvent.ACTION_MOVE:

                Log.d(TAG, "onInterceptTouchEvent1 action:ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.d(TAG, "onInterceptTouchEvent1 action:ACTION_UP");

                break;

            case MotionEvent.ACTION_CANCEL:

                Log.d(TAG, "onInterceptTouchEvent1 action:ACTION_CANCEL");

                break;

        }
        boolean b = false;
        Log.d(TAG, "onInterceptTouchEvent1 return:"+b);
        return b;

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        switch (action) {

            case MotionEvent.ACTION_DOWN:

                Log.d(TAG, "onTouchEvent1 action:ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.d(TAG, "onTouchEvent1 action:ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.d(TAG, "onTouchEvent1 action:ACTION_UP");

                break;

            case MotionEvent.ACTION_CANCEL:

                Log.d(TAG, "onTouchEvent1 action:ACTION_CANCEL");

                break;

        }
        boolean b = false;
        Log.d(TAG, "onTouchEvent1 return:"+b);
        return b;

    }

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

        // TODO Auto-generated method stub

        super.onLayout(changed, l, t, r, b);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        // TODO Auto-generated method stub

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

}

 类LayoutView2

 

package com.touchstudy;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class LayoutView2 extends LinearLayout {

    private final String TAG = "LayoutView2";

    public LayoutView2(Context context, AttributeSet attrs) {

        super(context, attrs);

        Log.d(TAG, TAG);

    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        switch (action) {

            case MotionEvent.ACTION_DOWN:

                Log.d(TAG, "onInterceptTouchEvent2 action:ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.d(TAG, "onInterceptTouchEvent2 action:ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.d(TAG, "onInterceptTouchEvent2 action:ACTION_UP");

                break;

            case MotionEvent.ACTION_CANCEL:

                Log.d(TAG, "onInterceptTouchEvent2 action:ACTION_CANCEL");

                break;

        }
        boolean b = false;
        Log.d(TAG, "onInterceptTouchEvent2 return:"+b);
        return b;

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        switch (action) {

            case MotionEvent.ACTION_DOWN:

                Log.d(TAG, "onTouchEvent2 action:ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.d(TAG, "onTouchEvent2 action:ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.d(TAG, "onTouchEvent2 action:ACTION_UP");

                break;

            case MotionEvent.ACTION_CANCEL:

                Log.d(TAG, "onTouchEvent2 action:ACTION_CANCEL");

                break;

        }
        
        boolean b = false;
        Log.d(TAG, "onTouchEvent2 return:"+b);
        return b;
    }

}

 类MyTextView

 

package com.touchstudy;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

public class MyTextView extends TextView {

    private final String TAG = "MyTextView";

    public MyTextView(Context context, AttributeSet attrs) {

        super(context, attrs);

        Log.d(TAG, TAG);

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        int action = ev.getAction();

        switch (action) {

            case MotionEvent.ACTION_DOWN:

                Log.d(TAG, "onTouchEvent_TextView action:ACTION_DOWN");

                break;

            case MotionEvent.ACTION_MOVE:

                Log.d(TAG, "onTouchEvent_TextView action:ACTION_MOVE");

                break;

            case MotionEvent.ACTION_UP:

                Log.d(TAG, "onTouchEvent_TextView action:ACTION_UP");

                break;

            case MotionEvent.ACTION_CANCEL:

                Log.d(TAG, "onTouchEvent_TextView action:ACTION_CANCEL");

                break;

        }
        boolean b = false;
        Log.d(TAG, "onTouchEvent_TextView return:"+b);
        return b;

    }

    public void onClick(View v) {

        Log.d(TAG, "onClick");

    }

    public boolean onLongClick(View v) {

        Log.d(TAG, "onLongClick");

        return false;

    }

}

onInterceptTouchEvent()是ViewGroup的一个方法,目的是在系统向该ViewGroup及其各个childView触发onTouchEvent()之前对相关事件进行一次拦截,由于ViewGroup会包含若干childView,因此需要能够统一监控各种touch事件的机会,因此纯粹的不能包含子view的控件是没有这个方法的,如LinearLayout就有,TextView就没有。

关于返回值的问题,如果return true,那么表示该方法消费了此次事件,如果return false,那么表示该方法并未处理完全,该事件仍然需要以某种方式传递下去继续等待处理,需要说明的是,如果 onTouchEvent针对down事件返回了false,那么之后的move和up事件即使没有被拦截,也是接收不到的,或者说识别不了.

onInterceptTouchEvent()使用也很简单,如果在ViewGroup里覆写了该方法,那么就可以对各种touch事件加以拦截。但是如何拦截,是否所有的touch事件都需要拦截则是比较复杂的,touch事件在onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。并且,针对down事件处理的返回值直接影响到后续move和up事件的接收和传递。

总结一下,基本的规则是:

1. 对于一个事件,如果没有被任何view拦截的话(所有方法都返回false),全程的顺序是

LayoutView1->LayoutView2->MyTextView依次调用onInterceptTouchEvent()

然后MyTextView->LayoutView2->LayoutView1依次调用onTouchEvent()

2. onInterceptTouchEvent()只负责拦截不拦截,onTouchEvent()只负责处理不处理,两者只要返回true,该事件就停止向后传递.

3. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理.

4. 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理。

5. 如果最终需要处理事件的view 的onTouchEvent()返回了true,则上一层次的view收不到该事件,且后续事件将可以继续传递给该view的onTouchEvent()处理.  

 

下面开始在代码中试验.

1.onInterceptTouchEvent()处理事件均返回false,onTouchEvent()处理事件均返回true



 这是最常见的情况,onInterceptTouchEvent并没有做任何改变事件传递时序的操作,效果上和没有覆写该方法是一样的。可以看到,各种事件的传递本身是自底向上的,次序是:LayoutView1->LayoutView2->MyTextView。事件在MyTextView的OnTouch中被处理,停止了向父组件传递.

 

2.LayoutView1的onInterceptTouchEvent()处理事件返回true,MyTextView的onTouchEvent()处理事件返回true


 由于LayoutView1在拦截第一次事件时return true,所以后续的事件(包括第一次的down)将由LayoutView1本身处理,事件不再传递下去。

 

3.LayoutView1,LayoutView2的onInterceptTouchEvent()处理事件返回false,MyTextView的onTouchEvent()处理事件返回false,LayoutView2的onTouchEvent()处理事件返回true



 由于MyTextView在onTouchEvent()中return false,down事件被传递给其父view,即LayoutView2的onTouchEvent()方法处理,由于在LayoutView2的onTouchEvent()中return true,所以down事件传递并没有上传到LayoutView1。注意,后续的move和up事件均被传递给LayoutView2的onTouchEvent()处理,而没有传递给MyTextView。


    
[2] getWidth()替0
    来源: 互联网  发布时间: 2014-02-18
getWidth()为0
一般在刚开始开发android时,会犯一个错误,即在View的构造函数中获取getWidth()和getHeight(),当一个view对象创建时,android并不知道其大小,所以getWidth()和getHeight()返回的结果是0,真正大小是在计算布局时才会计算,所以会发现一个有趣的事,即在onDraw( ) 却能取得长宽的原因。

如何在构造函数中如何取得长宽。

    width = activity.getWindowManager().getDefaultDisplay().getWidth();
    height = activity.getWindowManager().getDefaultDisplay().getHeight();


以上选自网络,但是我在自定义的layout里边自定义一个View,初始化时候取得View的getWidth()一直为零,我自己认为是只有屏幕显示后才能取得屏幕的大小,然后getWidth()值才不为0,所以可以另起一个线程判断不为零时再做别的事.

    
[3] java解压rar资料
    来源: 互联网  发布时间: 2014-02-18
java解压rar文件

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import de.innosystec.unrar.Archive;
import de.innosystec.unrar.rarfile.FileHeader;

public class Decompress {

public static boolean existZH(String str) {
String regEx = "[\\u4e00-\\u9fa5]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.find();
}

public static String getFileName(String fileName){
if (null == fileName && "".equals(fileName)) {
return "";
}
int index = fileName.lastIndexOf(".");
return fileName.substring(0, index);
}

public static boolean unrarFile(String rarFilePath, String extPlace){
boolean flag = false;
if (null == rarFilePath || "".equals(rarFilePath.trim())) {
System.out.println("rar文件路径为空.");
return flag;
} else {
int index = rarFilePath.lastIndexOf(".");
if (index > -1) {
String suffix = rarFilePath.substring(index + 1, rarFilePath.length());
if (!"rar".equalsIgnoreCase(suffix)) {
System.out.println("压缩文件格式不正确.");
return flag;
}
}
}
if (null == extPlace || "".equals(extPlace.trim())) {
System.out.println("解压路径为空.");
return flag;
}

Archive archive = null;
OutputStream os = null;

try {
File file = new File(rarFilePath);
String extDir = extPlace + getFileName(file.getName()) + File.separator;
archive = new Archive(file);
FileHeader fh = archive.nextFileHeader();

String fileName = null;
String path = null;
String dirPath = null;
File dir = null;
while (null != fh) {
fileName = fh.getFileNameW().trim();
if (!existZH(fileName)) {
fileName = fh.getFileNameString();
}

path = (extDir + fileName).replaceAll("\\\\", "/");
int end = path.lastIndexOf("/");
if (end > -1) {
dirPath = path.substring(0, end);
}

dir = new File(dirPath);
if (!dir.exists()) {
dir.mkdirs();
}

if (fh.isDirectory()) {
fh = archive.nextFileHeader();
continue;
}

os = new FileOutputStream(extDir + fileName);
archive.extractFile(fh, os);
os.flush();
os.close();

fh = archive.nextFileHeader();
}
flag = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != os) {
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != archive) {
try {
archive.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

return flag;
}
}

 

 

java-unrar-0.3.jar在附件中。


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3