安卓开发之scrollBy和scrollTo简述

 更新时间:2016年10月2日 16:23  点击:1784
下面我们来看一篇关于安卓开发之scrollBy和scrollTo简述的教程希望这篇文章可以帮助到各位深入理解到scrollBy和scrollTo的用法吧。

刚刚在学习listview滑动删除,要用到view的scrollBy和scrollTo,就研究了一下,下面分享一下:

先说scrollTo,

scrollTo(int x, int y):传入x,y坐标,将view移动到(-x,-y)位置

scrollBy(int x, int y):传入x,y坐标,将view向x正方向移动-x个单位,向y正方向移动-y个单位

假设x为正数,就向左移,反之向右

下面画个图举个例子:

无标题

红线框代表手机界面,黑框代表一个LinearLayout,id设为llayout;

下面调用:

llayout.scrollTo(-100,0);

效果:

这个时候再调用llayout.scrollTo(-100,0);图像是不会发生变化的,因为这个方法的作用是移动到固定的点

那么,这个时候再调用:llayout.scrollBy(-100,0);

图像就会变成这样:

即向右移动了100px,

这个时候假设再调用llayout.scrollTo(0,0);他又会回到初始位置了

 看scrollBy的方法可以看出:

scrollBy也是调用了scrollTo的方法,而参数是当前的Scroll坐标加上传入的坐标,即从当前位置移动(x,y)


public void scrollBy(int x, int y) {
    scrollTo(mScrollX + x, mScrollY + y);
}

可能有的同学会问,为什么参数是负的,走的确是正的方向,这个问题在view的某一句源码可以得到解释:

public void invalidate(int l, int t, int r, int b) {
    final int scrollX = mScrollX;
    final int scrollY = mScrollY;
    invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
}
负负得正,这样容易理解多了吧,至于为什么要减,各位可以自己去探索

 
使用通俗话总结下这两个方法:

假如两个人在跑步,scrollTo(-50,0)即移动到第50米,scrollBy(-50,0)即移动50米,当两人位于起点时,两方法等效

下面我们来看一篇关于安卓开发之Scroller.startScroll()方法简介,希望这篇文章能够让各位深入理解到Scroller.startScroll方法的用法。

上篇说到,可以使用scrollBy和scrollTo移动View,这里产生一个问题,加入一个View在屏幕的左上角即(0,0)位置,他调用

scrollTo(-300,-300)时,会立即跳过去,显得很突兀,如何让他平缓地划过去呢?就可以用本篇的方法了。


使用方法:

int startX;//滑动动作的起始点x坐标
int startY;//滑动动作的起始点y坐标
int dx;    //x轴偏移量向左为负,向右为正(即负值向右移,正值向左移)
int dy;    //y轴偏移量向左为负,向右为正(即负值向右移,正值向左移)
int duration;//时间,默认为250ms
注意:这里的dx和dy和上篇的scrollBy的参数相似,都是往哪个地方移动了多少,而不是往哪个点移动
Scroller mScroller=new Scroller(context);
mScroller.startScroll(startX,startY,dx,dy);
invalidate();//

除了上面的代码之外,还得重写View的computeScroll方法:

这里我的理解是:判断某一阶段滑动完成,就调用scrollTo方法,实现真正的移动

@Override
public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
        scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
        postInvalidate();
    }
    super.computeScroll();
}

可能大家还有点不明白,我还是来画图吧:

一个view,距离上边300px,距离左边300px,即他的坐标为(300,300);

那么这个时候,我们希望他从当前的这个位置,缓慢移动到(0,0),用时1秒,就这么写:

mScroller.startScroll(-300, -300, 300, 300,1000);

假设我们希望它从(300,300)移动到(100,100):

mScroller.startScroll(-300, -300, 200, 200,5000);

假设我们希望它从(300,300)移动到(200,200):

mScroller.startScroll(-300, -300, 100, 100,5000);

这样只是移动某段距离,那我们怎么样使它移动到一个固定的点呢?

我们可以这样做:假设我们想要移动到(100,100):


mScroller.startScroll(-300, -300, 0, 0, 500);
mScroller.setFinalX(100);
mScroller.setFinalY(100);
invalidate();

我为什么这样写呢?是有依据的,看一下startScroll的源码:

public void startScroll(int startX, int startY, int dx, int dy, int duration) {
    mMode = SCROLL_MODE;
    mFinished = false;
    mDuration = duration;
    mStartTime = AnimationUtils.currentAnimationTimeMillis();
    mStartX = startX;
    mStartY = startY;
    mFinalX = startX + dx;
    mFinalY = startY + dy;
    mDeltaX = dx;
    mDeltaY = dy;
    mDurationReciprocal = 1.0f / (float) mDuration;
}
 

其中:

mFinalX = startX + dx;
mFinalY = startY + dy;

就是把我们传进去的几个值加了一下,意思就是,我们传的dx,dy,就是我们移动的偏移量,受到起始数值的约束,

所以我们单独操控mFinalX、mFinalY就可以了.

最后解释一下computeScroll方法:


@Override
public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
        scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
        postInvalidate();
    }
    super.computeScroll();
}

首先把上面的例子拿来:

mScroller.startScroll(-300, -300, 300, 300,1000);
在(300,300)点,用时一秒,移动到(0,0),我们想一下,在一秒内完成这个操作,假设我们细分成100部分,即一部分为10ms,

那么在第一个10ms,    mScrollerd的getCurrX()就是-300+3=-270,getCurrX同理,即第一个10ms后,view需要向左边移动了3px,这个时候computeScroll调用了,我们先判断一下mScroller的第一个阶段是不是完成了,假设完成了,就调用scrollTo()方法。

这样经过100个部分,在我们看来,就是缓慢的移动过去了.

下面我们来看一篇关于Ionic + cordova 构建 webapp 项目的例子,希望此教程能够给各位同学带来帮助。

开发环境是Windows,ubuntu + mac同理,测试平台为android,ios同理。

1.安装node.js

https://nodejs.org/dist/v4.4.5/
http://nodejs.org/download/

2.设置npm镜像

npm config set registry https://registry.npm.taobao.org

3.安装 cordova+ionic

npm install -g cordova ionic
npm update -g cordova ionic //更新

4.创建APP项目

ionic start myapp [template]
template:blank(空项目)、tabs(带导航条)、sidemenu(带侧滑菜单)
ionic platform add android
ionic build android
ionic platform add ios
ionic build ios
ionic run android //连接数据线直接测试

安卓打包环境配置:

1.JDK安装配置

   下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html
    安装的时候,jdk、jre装在同级目录下。
    配置环境变量,在系统变量中新建 JAVA_HOME,值为jdk的安装目录 D:\Program Files\Java\jdk1.8.0_91。在PATH中添加 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin 。系统变量中新建 CLASSPATH,值为 .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar。
    java -version

2.Android SDK

    下载地址:http://developer.android.com/sdk/index.html 或 http://www.android-studio.org/
    安装完成后配置环境变量,在系统变量中新建 ANDROID_HOME,值为安装目录 D:\Program Files\Android\android-sdk 。在PATH中添加 D:\Program Files\Android\android-sdk;%ANDROID_HOME%\tools; 。
    android -h

这时候SDK安装工具算是好了,然后就可以从SDK Manager中管理安装需要的SDK版本和GOOGLE API版本和文档了。这里主要看你安装的ionic对应的android版本,在你的ionic项目目录的platforms\android\project.properties文件中可以找到target=android-23。这里标识了项目所用的API版本,后面的数字刚好对应你在SDK Manager中看到的那些API后面的数字。

问题:

下面我们来看一篇关于Json与Gson之简单对象转化和带泛型的List转化的例子,希望这篇文章能够给各位带来帮助。


Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。在Android Studio中直接引用

compile 'com.google.code.gson:gson:2.2.4'
下面先看一下怎么转化对象:

实体类如下:

public class TestEneity {
 
    /**
     * image : image/mango_cover.jpg
     * content : 火爆进口马来西亚特产大金芒果包邮500G
     * price : 18.9
     * PreferentialPrice : 14.9
     * you : 免邮费
     * number : 23
     */
 
    private String image;
    private String content;
    private String price;
    private String PreferentialPrice;
    private String you;
    private String number;
 
    public String getImage() {
        return image;
    }
 
    public void setImage(String image) {
        this.image = image;
    }
 
    public String getContent() {
        return content;
    }
 
    public void setContent(String content) {
        this.content = content;
    }
 
    public String getPrice() {
        return price;
    }
 
    public void setPrice(String price) {
        this.price = price;
    }
 
    public String getPreferentialPrice() {
        return PreferentialPrice;
    }
 
    public void setPreferentialPrice(String PreferentialPrice) {
        this.PreferentialPrice = PreferentialPrice;
    }
 
    public String getYou() {
        return you;
    }
 
    public void setYou(String you) {
        this.you = you;
    }
 
    public String getNumber() {
        return number;
    }
 
    public void setNumber(String number) {
        this.number = number;
    }
}

使用方式:


TestEneity testEntity=new TestEneity();
testEntity.setImage("image/mango_cover.jpg");
testEntity.setContent("火爆进口马来西亚特产大金芒果包邮500G");
testEntity.setPrice("18.9");
testEntity.setPreferentialPrice("14.9");
testEntity.setYou("免");
testEntity.setNumber("23");
 
System.out.println("----------简单对象之间的转化-------------");
// 简单的bean转为json
Gson gson=new Gson();
String s1 = gson.toJson(testEntity);
System.out.println("简单Bean转化为Json===" + s1);
 
// json转为简单Bean
TestEneity tset = gson.fromJson(s1, TestEneity.class);
System.out.println("Json转为简单Bean===" + tset);

List<TestEneity> testEntityList=new ArrayList<>();
for(int i=0;i<3;i++){
TestEneity testEntity=new TestEneity();
testEntity.setImage("image/mango_cover.jpg");
testEntity.setContent("火爆进口马来西亚特产大金芒果包邮500G");
testEntity.setPrice("18.9");
testEntity.setPreferentialPrice("14.9");
testEntity.setYou("免");
testEntity.setNumber("23");
testEntityList.add(testEntity);
System.out.println("----------带泛型的List之间的转化-------------");
// 带泛型的list转化为json
Gson gson=new Gson();
String s2 = gson.toJson(testEntityList);
System.out.println("带泛型的list转化为json==" + s2);
 
// json转为带泛型的list
List<TestEneity> retList = gson.fromJson(s2,
new TypeToken<List<TestEneity>>() {
}.getType());
for (TestEneity stu : retList) {
System.out.println(stu);
}
}

下面我们来看一篇关于没有配置NDK的Path环境变量而运行ndk-build命令时报错问题原因分析与此问题的解决办法,具体的如下。

如果在PATH环境变量下配置NDK的根目录,那么将有可能会报'ndk-build'isnotrecognizedasaninternalorexternalcommand,operableprogramorbatchfile.的错误.
如下:

'ndk-build'isnotrecognizedasaninternalorexternalcommand,operableprogramorbatchfile.

解决办法

这时,只需要将NDK的根目录路径拷贝到path中即可.

[!--infotagslink--]

相关文章