日期: 2021 年 7 月 1 日

研究了下,ios 没有随机生成字符串的方法,然后我就变通的搞成功了,哈哈!

不是很完美,但是 可以用。

方法用二个步骤:

*步是 随机生成一个数字

int index = arc4random() % 10; //随机生成0-9 的数字
第二步是对这个数字进行MD5 散列,这样就有随机的字符串了,哈哈!

-(NSString*) md5:(NSString*)str{
const char *cStr = [str UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), result );

return [NSString stringWithFormat:
@”%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X”,
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];

}

别忘记加入头文件
#import <commoncrypto/CommonDigest.h>

这样就生成了随机的字符串。

iOS 生成随机字符串 从指定字符串随机产生n个长度的新字符串

  • 随机字符串 – 生成指定长度的字符串
  1. -(NSString *)randomStringWithLength:(NSInteger)len {
  2. NSString *letters = @”abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789″;
  3. NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
  4. for (NSInteger i = 0; i < len; i++) {
  5. [randomString appendFormat: @”%C”, [letters characterAtIndex: arc4random_uniform([letters length])]];
  6. }
  7. return randomString;
  8. }
  • 指定字符串随机生成指定长度的新字符串
  1. -(NSString *)randomStringWithLength:(NSInteger)len String:(NSString *)letters {
  2. NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
  3. for (NSInteger i = 0; i < len; i++) {
  4. [randomString appendFormat: @”%C”, [letters characterAtIndex: arc4random_uniform([letters length])]];
  5. }
  6. return randomString;
  7. }
  8. //调用方法
  9. -(NSString *)generateCard{
  10. //HXMF 123456789TJQK
  11. NSString *color =[self randomStringWithLength:1 String:@”HXMF”];
  12. NSString *number = [self randomStringWithLength:1 String:@”123456789TJQK”];
  13. return [NSString stringWithFormat:@”%@%@”,color,number];

Unity IOS包在IPhone出现闪退

在iphone上运行时unity还没有执行到我自己的代码就在这句代码上挂掉了UnityInitApplicationGraphics(UNITY_FORCE_DIRECT_RENDERING);

解决办法

%title插图%num

在unit导出xcode包时我选择的API是自动选择渲染的API接口,就是这个选项造成的问题‘

%title插图%num

取消勾选该选项后会看到有3个api

%title插图%num

取消掉Metal渲染的这个api就行了,有关MetalAPI的请自行百度

1042.  字符统计(20) python篇

1042.
 字符统计(20) python篇
1042. 字符统计(20)
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
请编写程序,找出一段给定文字中出现*频繁的那个英文字母。
输入格式:
输入在一行中给出一个长度不超过1000的字符串。字符串由ASCII码表中任意可见字符及空格组成,至少包含1个英文字母,以回车结束(回车不算在内)。
输出格式:
在一行中输出出现频率*高的那个英文字母及其出现次数,其间以空格分隔。如果有并列,则输出按字母序*小的那个字母。统计时不区分大小写,输出小写字母。
输入样例:
This is a simple TEST.  There ARE numbers and other symbols 1&2&3………..
输出样例:
e 7
a=list(map(chr,range(ord(‘a’),ord(‘z’)+1)))
n=input()
b=[]
n=n.lower()
for i in range(26):
    b.append(n.count(a[i]))
c=max(b)
d=[]
for x,y in enumerate(b):
    if y==c:
        d.append(a[x])
print(min(d),c)

1055. 集体照 (25) python篇

1055. 集体照 (25) python篇
1055. 集体照 (25)
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
拍集体照时队形很重要,这里对给定的N个人K排的队形设计排队规则如下:
每排人数为N/K(向下取整),多出来的人全部站在*后一排;
后排所有人的个子都不比前排任何人矮;
每排中*高者站中间(中间位置为m/2+1,其中m为该排人数,除法向下取整);
每排其他人以中间人为轴,按身高非增序,先右后左交替入队站在中间人的两侧(例如5人身高为190、188、186、175、170,则队形为175、188、190、186、170。这里假设你面对拍照者,所以你的左边是中间人的右边);
若多人身高相同,则按名字的字典序升序排列。这里保证无重名。
现给定一组拍照人,请编写程序输出他们的队形。
输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出两个正整数N(<=10000,总人数)和K(<=10,总排数)。随后N行,每行给出一个人的名字(不包含空格、长度不超过8个英文字母)和身高([30, 300]区间内的整数)。
输出格式:
输出拍照的队形。即K排人名,其间以空格分隔,行末不得有多余空格。注意:假设你面对拍照者,后排的人输出在上方,前排输出在下方。
输入样例:
10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159
输出样例:
Bob Tom Joe Nick
Ann Mike Eva
Tim Amy John
def ranking(person):      #定义函数使其依次返回身高的负数,人名
    return -int(person[1]),person[0]
num,k = list(map(int,input().split()))
person=[]                 #存储数据的列表
for i in range(num):
    person.append(input().split())
order = sorted(person,key=ranking)     #排序后的数据列表
hang,last= num//k,num//k+num%k     #除*后一行外每行的人数以及*后一行的人数
b=[]                               #用于每行的队列的输出
sum=0                              #用于左右交替插入的指针
for i in range(num):
    if sum%2==0:
        b.append(order[i][0])      #在右边插入人名
    else:
        b.insert(0,order[i][0])    #在左边插入人名
    sum+=1
    if sum==last:                  #如果一行插入完毕,则输出该行,并把列表b以及指针sum归0,方便下一行的插入操作
        print(” “.join(b))
        last=hang
        b=[]
        sum=0

Android酷炫实用的开源框架

Android酷炫实用的开源框架(UI框架)

前言

忙碌的工作终于可以停息一段时间了,*近突然有一个想法,就是自己写一个app,所以找了一些合适开源控件,这样更加省时,再此分享给大家,希望能对大家有帮助,此博文介绍的都是UI上面的框架,接下来会有其他的开源框架(如:HTTP框架、DB框架)。

1.Side-Menu.Android
分类侧滑菜单,Yalantis 出品。

image
2.Context-Menu.Android
可以方便快速集成漂亮带有动画效果的上下文菜单,Yalantis出品。

image
3.Pull-to-Refresh.Rentals-Android
提供一个简单可以自定义的下拉刷新实现,Yalantis 出品。

image
4.Titanic
可以显示水位上升下降的TextView

image
5.AndroidSwipeLayout
滑动Layout,支持单个View,ListView,GridView

image
6.Android Typeface Helper
可以帮你轻松实现自定义字体的库

image
7.android-lockpattern
Android的图案密码解锁

 

APP示例:Android开机的图案密码解锁,支付宝的密码解锁
image
8.ToggleButton
状态切换的 Button,类似 iOS,用 View 实现

image
9.WilliamChart
绘制图表的库,支持LineChartView、BarChartView和StackBarChartView三中图表类型,并且支持 Android 2.2及以上的系统。

image
10.实现滑动ViewPager渐变背景色

image
11.Euclid
用户简历界面,Yalantis 出品。

image
12.InstaMaterial
Instagram的一组Material 风格的概念设计

image
13.SpringIndicator

使用bezier实现粘连效果的页面指示

image
14.BezierDemo

仿qq消息气泡拖拽消失的效果。

image
15.FoldableLayout

折叠的信纸被打开一样的动画效果

image
16.Taurus
下拉刷新,Yalantis 出品。(是不是有点似曾相识呢?)

image
17.PersistentSearch

在点击搜索的时候控件在原有位置显示输入框。

image
18.circular-progress-button

带进度显示的Button

image
19.discrollview

当上下滚动的时候子元素会呈现不同动画效果的scrollView,网页上称之为:视差滚动

image
20.sweet-alert-dialog

一个带动画效果的自定义对话框样式

image
21.android-floating-action-button

Material Desig风格的浮动操作按钮

image
22.android-collapse-calendar-view

可以在月视图与周视图之间切换的calendar控件

image
23.NumberProgressBar

个简约性感的数字进度条

image
24.CircularProgressView

CircularProgressView 是通过自定义view的方式实现的Material风格的加载提示控件,兼容任何版本。

image
25.OriSim3D-Android

opengl 实现了各种折纸效果,模拟了从一张纸折叠成一条船的整个过程

image

 

iOS方法名称混淆之随机字符串和随机单词组合

iOS方法名的混淆可以使用宏定义的方式,方便管理。
但是目前混淆成随机字母的组合很难上架,会被Apple警告语意不明确。因此可以尝试通过单词组合的方式来混淆,通过读取单词库,获取不同的单词组合来实现混淆方法名。

通过shell脚本实现,具体代码如下:

TABLENAME=symbols
#混淆时生成的数据库文件
SYMBOL_DB_FILE=”./symbols”
#需要混淆的方法名称
STRING_SYMBOL_FILE=”./func.list”
#混淆后生成的宏定义
HEAD_FILE=”./codeObfuscation.h”
#单词库文件,一行1个单词
WORDS_FILE=”./words.txt”
export LC_CTYPE=C

#维护数据库方便日后作排重
createTable()
{
echo “create table $TABLENAME(src text, des text);” | sqlite3 $SYMBOL_DB_FILE
}

insertValue()
{
echo “insert into $TABLENAME values(‘$1′ ,’$2′);” | sqlite3 $SYMBOL_DB_FILE
}

query()
{
echo “select * from $TABLENAME where src=’$1’;” | sqlite3 $SYMBOL_DB_FILE
}

#随机字符串
ramdomString()
{
openssl rand -base64 64 | tr -cd ‘a-zA-Z’ |head -c 16
}

#字符串首字母大写
capitalizedString() {
str=$1
firstLetter=`echo ${str:0:1} | awk ‘{print toupper($0)}’`
otherLetter=${str:1}
result=$firstLetter$otherLetter
echo $result
}

#从单词库中获取随机字符串
ramdomString2()
{
list=(`cat $WORDS_FILE`)
#1000为单词库中的单词个数,不能超过总数
randomIndex1=$[$RANDOM%1000+1]
words1=${list[$randomIndex1]}
#取出来第2个单词并将首字母大写
randomIndex2=$[$RANDOM%1000+1]
words2=${list[$randomIndex2]}
newWords2=$(capitalizedString $words2)
#将2个单词拼接,也可以3个、4个等更多
totalWords=$words1$newWords2
echo $totalWords
}

rm -f $SYMBOL_DB_FILE
rm -f $HEAD_FILE
createTable

touch $HEAD_FILE
echo ‘#ifndef Demo_codeObfuscation_h
#define Demo_codeObfuscation_h’ >> $HEAD_FILE
echo “//confuse string at `date`” >> $HEAD_FILE
cat “$STRING_SYMBOL_FILE” | while read -ra line; do
if [[ ! -z “$line” ]]; then
ramdom=$(ramdomString2)
#ramdom=`ramdomString2`
insertValue $line $ramdom
echo “#define $line $ramdom” >> $HEAD_FILE
fi
done
echo “#endif” >> $HEAD_FILE

sqlite3 $SYMBOL_DB_FILE .dump

方法列表文件示例:

图1:

%title插图%num

单词库文件示例:

图1:

%title插图%num

生成的宏定义示例:

图1:

%title插图%num

Unity适配iOS14时app闪退原因之一

*近在iOS14设备上测试Unity游戏(App类似),由于之前没注意修改info.plist中BundleName属性,一直写的是中文名称,在iOS14之前的设备上没有闪退情况,但是换到iOS14设备后就出现闪退情况。

解决方法:info.plist中的BundleName属性必须要设置为英文,BundleDisplayName属性设置成中文没有问题。

Android动画框架之视图动画基本使用

之前在学习View 滑动的时候其实就是View动画的一种展现形式了,当时介绍了有7中方法可以实现View的滑动,截止目前还有Sroller,动画以及ViewDragHelper实现没有介绍,今天的内容里面就包含了部分View的滑动实现,这里说部分主要有两个原因:

今天介绍的视图动画实现的滑动是不可交互的滑动实现
后面可以通过3.0之后的属性动画完整实现

1,基础知识
好的,那几天就来简单看一下Android动画框架中的视图动画的基本使用。首先,先来看一个效果图,里面包含了视图动画可以实现的独立动画效果

%title插图%num

从上面的效果图可以看出,视图动画API主要可以帮助我们实现View的以下几个电话效果:

透明度变化
旋转(围绕一个坐标点)
伸缩(围绕一个坐标点)
平移
对应的API分别为:

AlphaAnimation
AlphaAnimation alphaAnimation1=new AlphaAnimation(1,0);
alphaAnimation1.setDuration(timeLength);
RotateAnimation
RotateAnimation rotateAnimation1=new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation1.setDuration(timeLength);
ScaleAnimation
ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scaleAnimation.setDuration(timeLength);
TranslateAnimation
TranslateAnimation translateAnimation=new TranslateAnimation(startX,endX,startY,endY);
translateAnimation.setDuration(timeLength);
这些API都是Animation的子类,文档如下:

android.view.animation
类 Animation
java.lang.Object
android.view.animation.Animation
所有已实现的接口:

Cloneable

直接已知子类:

AlphaAnimation, AnimationSet, RotateAnimation, ScaleAnimation, TranslateAnimation

由文档可以看出,它还有一个子类是AnimationSet,顾名思义就是动画集合的意思,也就是说添加一组动画到View,然后这些动画效果同时展示在View上,这样就会有一个组合动画的效果。比如:

AnimationSet set=new AnimationSet(true);
……
set.addAnimation(alphaAnimation1);
set.addAnimation(alphaAnimation2);
set.addAnimation(rotateAnimation1);
set.addAnimation(scaleAnimation);
set.addAnimation(translateAnimation);
testImage.startAnimation(set);
此外,针对每一个动画对象,我们都可以为其添加动画状态监听,这样就可以在动画开始和结束的时候做一些逻辑操作,比如:

scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this,”平移动画开始”,Toast.LENGTH_SHORT).show();
testImage.startAnimation(translateAnimation);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});
针对每一个动画对象,我们都可以在动画的三种状态的时候做逻辑操作:

start
end
repeat

2 案例实现
实现步骤:

*步:构建布局,一个按钮,两个ImageView并且重叠,下面一张ImageView主要用于记录上面一张ImageView的初始位置,方便后面验证视图动画完成的知识View显示的变化,交互时间还是停留在初始位置

第二步:获取动画对象,设置状态监听,实现动画间平滑衔接,并吐司信息

第三步:根据展示效果给ImageView添加动画

代码:

activity_main.xml代码:

<?xml version=”1.0″ encoding=”utf-8″?>
<android.support.constraint.ConstraintLayout xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:app=”http://schemas.android.com/apk/res-auto”
xmlns:tools=”http://schemas.android.com/tools”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
tools:context=”com.hfut.operationanimation.MainActivity”>

<Button
android:id=”@+id/controll_button”
android:layout_marginTop=”30dp”
android:textSize=”30dp”
android:text=”动画测试”
android:onClick=”animationTest”
app:layout_constraintLeft_toLeftOf=”parent”
app:layout_constraintRight_toRightOf=”parent”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content” />

<ImageView
android:layout_marginTop=”30dp”
android:id=”@+id/test_image_background”
app:layout_constraintTop_toBottomOf=”@+id/controll_button”
app:layout_constraintLeft_toLeftOf=”parent”
app:layout_constraintRight_toRightOf=”parent”
android:src=”@color/colorAccent”
android:layout_width=”180dp”
android:layout_height=”240dp” />
<ImageView
android:layout_marginTop=”30dp”
android:id=”@+id/test_image”
app:layout_constraintTop_toBottomOf=”@+id/controll_button”
app:layout_constraintLeft_toLeftOf=”parent”
app:layout_constraintRight_toRightOf=”parent”
android:src=”@drawable/testimage”
android:layout_width=”180dp”
android:layout_height=”240dp” />

</android.support.constraint.ConstraintLayout>

MainActivity代码:

package com.hfut.operationanimation;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.Toast;

/**
* @author why
* @date 2018-9-7 21:22:18
*/
public class MainActivity extends AppCompatActivity {

ImageView testImage;
int startX;
int startY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testImage=findViewById(R.id.test_image);
//监听当前Image的点击事件
testImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,”Image被点击了”,Toast.LENGTH_SHORT).show();
}
});

startX=(int)testImage.getX();
startY=(int)testImage.getY();
}

public void animationTest(View view){

//动画集合对象
final AnimationSet set=new AnimationSet(true);

//透明度动画
AlphaAnimation alphaAnimation1=new AlphaAnimation(1,0);
alphaAnimation1.setDuration(1000);
final AlphaAnimation alphaAnimation2=new AlphaAnimation(0,1);
alphaAnimation2.setDuration(1000);
//旋转动画
final RotateAnimation rotateAnimation1=new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation1.setDuration(2000);
//缩放动画
final ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scaleAnimation.setDuration(2000);
//平移动画
final TranslateAnimation translateAnimation=new TranslateAnimation(startX,200,startY,300);
translateAnimation.setDuration(2000);
//设置平移后是否留在当前位置
translateAnimation.setFillAfter(true);

translateAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this,”平移动画结束”,Toast.LENGTH_SHORT).show();
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// testImage.startAnimation(set);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});

scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this,”平移动画开始”,Toast.LENGTH_SHORT).show();
testImage.startAnimation(translateAnimation);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});

rotateAnimation1.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this,”缩放动画开始”,Toast.LENGTH_SHORT).show();
testImage.startAnimation(scaleAnimation);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});

alphaAnimation2.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {

}

@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this,”旋转动画开始”,Toast.LENGTH_SHORT).show();
testImage.startAnimation(rotateAnimation1);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});
//View开启动画
testImage.startAnimation(alphaAnimation1);
alphaAnimation1.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(MainActivity.this,”透明度动画开始”,Toast.LENGTH_SHORT).show();
}

@Override
public void onAnimationEnd(Animation animation) {
testImage.startAnimation(alphaAnimation2);
}

@Override
public void onAnimationRepeat(Animation animation) {

}
});

// set.addAnimation(alphaAnimation1);
// set.addAnimation(alphaAnimation2);
// set.addAnimation(rotateAnimation1);
// set.addAnimation(scaleAnimation);
// set.addAnimation(translateAnimation);
// testImage.startAnimation(set);
}
}

这里说几点注意事项

上面的示例旋转和伸缩使用的坐标是相对参数,我们也可以使用*对坐标加上View自身宽高实现,可参见Android中实现滑动(上)—-基础知识,这样就可以理解如何获取当前View的*对坐标,下面就是计算View中心点*对坐标的简易表达式:
rotateX=x+view.width/2;

rotateY=y+view.height/2;

平移动画完成后,如果不设置其停留在平移后的当前位置,则默认会返回初始位置
在验证ImageView交互位置未移动的现象,需要给ImageView设置一下点击之后的逻辑
​​​​​​​到这里,Android中关于视图动画的基本使用就简单介绍到这里了,使用其实还是蛮简单的。
————————————————

Android中实现滑动-实现(2)

在了解了前面介绍的基础知识之后,下面就来看看具体的滑动实现,接下来会介绍7种方法,主要是结合《Android群英传》中学习的知识展开。这七种方法分别是:

(1)View绘制时的layout方法

(2)View绘制时根据系统封装好的offSetLeftAndRight以及offSetTopAndBottom接口实现View的布局定位

(3)通过View的布局参数layoutParams来重置View的margin值实现布局重新定位

(4)通过View的scrollTo和scrollBy方法

(5)通过Scroller类实现

(6)通过属性动画实现

(7)通过ViewDragHelper实现

对于滑动的实现,我会分为四个部分讲解,*部分讲述(1)(2)(3)的实现方法,第二部分讲述(4)和(5)的实现,第三部分讲述属性动画方法实现,第四部分也是较复杂的部分讲述(7)的实现,下面我们就开始吧。本部分主要介绍scrollTo和scrollBy以及Scroller使用

1,scrollTo和scrollBy
任何一个View子类对象都可以调用这两个接口

1.1 两者的关系
scrollBy源码:

/**
* Move the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the amount of pixels to scroll by horizontally
* @param y the amount of pixels to scroll by vertically
*/
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
所以scrollBy实现的本质也是scrollTo

1.2 两者的作用和区别
(1)scrollTo(),view移动到指定坐标点

(2)scrollBy(),view依据当前的坐标点结合传入的偏移量进行移动

移动的效果:

如果是ViewGroup,那么屏幕展示的移动效果实际上是移动的其子view

如果是ImageView,Button这样的控件,那么屏幕展示的移动效果实际上是移动的其Content

比如下图示例:

%title插图%num

我们移动的View,本质上移动的却是其Content,所以如果我们想实现移动一个View的效果,只需要移动其父布局即可。需要注意的是这里有一个相对的概念,也即子View向左移动,父布局就需要向右移动;上下也是同理。下面就来看看具体的示例:

2,代码示例
2.1 简单移动测试
ScrollActivity代码:

package com.hfut.operationscroll;

import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

/**
* @author why
* @date 2018-8-19 16:48:41
*/
public class ScrollActivity extends AppCompatActivity {

int lastX = 0;
int lastY = 0;
private static final String TAG = “MainActivity”;
Button button;
LinearLayout linearLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scroll);
button = findViewById(R.id.test_button);
linearLayout=findViewById(R.id.test_layout);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, “onTouch: “+ System.currentTimeMillis());
//方式一,通过视图坐标系计算偏移量
int offX = x – lastX;
int offY = y – lastY;
v.scrollBy(-offX,-offY);
linearLayout.scrollBy(-offX,-offY);
break;
default:
break;
}
return true;
}
});
}

}
activity_scroll.xml代码:

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:app=”http://schemas.android.com/apk/res-auto”
xmlns:tools=”http://schemas.android.com/tools”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:id=”@+id/test_layout”
android:orientation=”vertical”
tools:context=”.MainActivity”>

<Button
android:id=”@+id/test_button”
android:layout_width=”400dp”
android:layout_height=”400dp”
android:text=”拖我移动” />

</LinearLayout>
代码和*部分差不多,偏移量的计算都一样,其中:

case MotionEvent.ACTION_MOVE:
Log.d(TAG, “onTouch: “+ System.currentTimeMillis());
int offX = x – lastX;
int offY = y – lastY;
v.scrollBy(-offX,-offY);
linearLayout.scrollBy(-offX,-offY);
break;
部分,里面两行关于移动的代码,如果把*行注释掉,那么按钮和里面的text一起同步移动,如果两行全放开,那么按钮里面的text也会相对button边框移动,运行代码:

%title插图%num

v.scrollBy(-offX,-offY);
注释后:

%title插图%num

注释前:

%title插图%num

2.2 使用scrollBy或者scrollTo模拟平滑滑动
我们知道,使用这两个接口实现的滑动都是瞬间完成的,给客户的体验很不好,下面就结合这两个方法以及Timer和Handler实现一个平滑的滑动,因为都是基础知识,这里直接给出代码:

ScrollActivity代码:

package com.hfut.operationscroll;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.Switch;

import java.sql.Time;
import java.util.Timer;
import java.util.TimerTask;

/**
* @author why
* @date 2018-8-19 17:14:10
*/
public class ScrollActivity extends AppCompatActivity {

public static final int DESTINATION=1;
public static final int STARTPOINT=0;
int quickCount = 1;
int slowCount = 1;
LinearLayout quickLinearLayout;
LinearLayout slowLinearLayout;
Switch slowOne;
Switch quickOne;
Scroller scroller;
Button quickTrigger;
Button slowTrigger;
int movedDis = 0;
int x = 0;
int increment = 10;

Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DESTINATION:
slowTrigger.setText(“回来”);
slowOne.setChecked(true);
break;
case STARTPOINT:
slowTrigger.setText(“慢移”);
slowOne.setChecked(false);
break;
default:
break;
}
}
};

private static final String TAG = “ScrollerActivity”;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scroller);
quickLinearLayout = findViewById(R.id.quick_move_layout);
slowLinearLayout = findViewById(R.id.slow_move_layout);
slowOne = findViewById(R.id.slow_runner);
quickOne = findViewById(R.id.quick_runner);
quickTrigger = findViewById(R.id.quick_button);
slowTrigger = findViewById(R.id.slow_button);
x = (int) quickOne.getX();
}

public void quickMove(View view) {

if (quickCount % 2 == 1) {
//Log.d(TAG, “quickMove: ” + total);
//考虑到其本身的长度,所以这里减少了100sp
quickLinearLayout.scrollBy(-(650 – x – 100), 0);
quickOne.setChecked(true);
quickTrigger.setText(“回来”);
} else {
quickLinearLayout.scrollBy(650 – x – 100, 0);
quickOne.setChecked(false);
quickTrigger.setText(“瞬移”);
}
quickCount++;
}

public void slowMove(View view) {
if (slowCount % 2 == 1) {
movedDis = 0;
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (540 – x >= movedDis) {
movedDis += increment;
slowLinearLayout.scrollBy(-increment, 0);
} else {
Message message=new Message();
message.what=DESTINATION;
handler.sendMessage(message);
timer.cancel();
}
}
}, 200, 50);
} else {
movedDis = 0;
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (540 – x >= movedDis) {
movedDis += increment;
slowLinearLayout.scrollBy(increment, 0);
} else {
Message message=new Message();
message.what=STARTPOINT;
handler.sendMessage(message);
timer.cancel();
}
}
}, 200, 50);
}
slowCount++;
}
}

activity_scroll.xml代码:

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:app=”http://schemas.android.com/apk/res-auto”
xmlns:tools=”http://schemas.android.com/tools”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:orientation=”vertical”
tools:context=”com.hfut.operationscroll.ScrollActivity”>

<LinearLayout
android:layout_width=”match_parent”
android:layout_height=”wrap_content”>
<Button
android:text=”瞬移”
android:id=”@+id/quick_button”
android:onClick=”quickMove”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content” />
<LinearLayout
android:id=”@+id/quick_move_layout”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”>
<Switch
android:id=”@+id/quick_runner”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginTop=”15sp” />
</LinearLayout>

</LinearLayout>

<LinearLayout
android:layout_width=”match_parent”
android:layout_height=”wrap_content”>
<Button
android:text=”慢移”
android:id=”@+id/slow_button”
android:onClick=”slowMove”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content” />

<LinearLayout
android:id=”@+id/slow_move_layout”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”>

<Switch
android:id=”@+id/slow_runner”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginTop=”15sp” />
</LinearLayout>

</LinearLayout>

</LinearLayout>

运行结果:

%title插图%num

这部分主要还是理解使用这种移动的原理,这对于后面的难点滑动冲突问题的解决至关重要。
————————————————

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速