How can i horizontally scroll in the appium
like for Vertical scroll we do
driver.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView("")");
is there like that???
You can set the UiSelector to scrollable and set direction of scrolling
driver().findElementByAndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true)."
+ "resourceId(\"<id of scrollable control>\"))"
+ ".setAsHorizontalList().scrollIntoView(new UiSelector().textContains(\"<text to search for>\"))");
Link gives details about UiScrollable
You can Use this way this will work horizontal and also by changing scroll start and scroll end you can use same code for vertical scroll also.
public void scrollHorizontal(double value1,double value2) {
Dimension dimension =driver.manage().window().getSize();
Double scrollheight = dimension.getHeight()*value1;
int scrollStart = scrollheight.intValue();
Double scrollheightEnd = dimension.getHeight()*value2;
int scrollEnd = scrollheightEnd.intValue();
new TouchAction((PerformsTouchActions)driver)
.press(PointOption.point(scrollStart,0))
.waitAction(WaitOptions.waitOptions(Duration.ofSeconds(2)))
.moveTo(PointOption.point(scrollEnd , 0))
.release()
.perform(); }
Use below method for horizontally scrolling:
public static void swipeHorizontal(AppiumDriver driver, double startPercentage, double finalPercentage, double anchorPercentage, int duration) throws Exception {
Dimension size = driver.manage().window().getSize();
int anchor = (int) (size.height * anchorPercentage);
int startPoint = (int) (size.width * startPercentage);
int endPoint = (int) (size.width * finalPercentage);
new TouchAction(driver).press(startPoint, anchor).waitAction(Duration.ofMillis(duration)).moveTo(endPoint, anchor).release().perform();
}
Call above method by:
swipeHorizontal((AppiumDriver) driver,0.9,0.01,0.5,2000);
This applies in all directions:
enum:
public enum DIRECTION {
DOWN, UP, LEFT, RIGHT;
}
actual code:
public static void swipe(MobileDriver driver, DIRECTION direction, long duration) {
Dimension size = driver.manage().window().getSize();
int startX = 0;
int endX = 0;
int startY = 0;
int endY = 0;
switch (direction) {
case RIGHT:
startY = (int) (size.height / 2);
startX = (int) (size.width * 0.90);
endX = (int) (size.width * 0.05);
new TouchAction(driver)
.press(startX, startY)
.waitAction(Duration.ofMillis(duration))
.moveTo(endX, startY)
.release()
.perform();
break;
case LEFT:
startY = (int) (size.height / 2);
startX = (int) (size.width * 0.05);
endX = (int) (size.width * 0.90);
new TouchAction(driver)
.press(startX, startY)
.waitAction(Duration.ofMillis(duration))
.moveTo(endX, startY)
.release()
.perform();
break;
case UP:
endY = (int) (size.height * 0.70);
startY = (int) (size.height * 0.30);
startX = (size.width / 2);
new TouchAction(driver)
.press(startX, startY)
.waitAction(Duration.ofMillis(duration))
.moveTo(endX, startY)
.release()
.perform();
break;
case DOWN:
startY = (int) (size.height * 0.70);
endY = (int) (size.height * 0.30);
startX = (size.width / 2);
new TouchAction(driver)
.press(startX, startY)
.waitAction(Duration.ofMillis(duration))
.moveTo(startX, endY)
.release()
.perform();
break;
}
}
usage:
swipe(driver, Util.DIRECTION.RIGHT);
Hope this helps,
Related
I want to a recycler view like below image. Means I want to max height and width of middle recycler view item in a horizontal recycler view.
I found a solution from a link, you may follow it accordingly.
public class CenterZoomLayoutManager extends LinearLayoutManager {
private final float mShrinkAmount = 0.15f;
private final float mShrinkDistance = 0.9f;
public CenterZoomLayoutManager(Context context) {
super(context);
}
public CenterZoomLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
#Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
int orientation = getOrientation();
if (orientation == VERTICAL) {
int scrolled = super.scrollVerticallyBy(dy, recycler, state);
float midpoint = getHeight() / 2.f;
float d0 = 0.f;
float d1 = mShrinkDistance * midpoint;
float s0 = 1.f;
float s1 = 1.f - mShrinkAmount;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
float childMidpoint =
(getDecoratedBottom(child) + getDecoratedTop(child)) / 2.f;
float d = Math.min(d1, Math.abs(midpoint - childMidpoint));
float scale = s0 + (s1 - s0) * (d - d0) / (d1 - d0);
child.setScaleX(scale);
child.setScaleY(scale);
}
return scrolled;
} else {
return 0;
}
}
#Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
int orientation = getOrientation();
if (orientation == HORIZONTAL) {
int scrolled = super.scrollHorizontallyBy(dx, recycler, state);
float midpoint = getWidth() / 2.f;
float d0 = 0.f;
float d1 = mShrinkDistance * midpoint;
float s0 = 1.f;
float s1 = 1.f - mShrinkAmount;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
float childMidpoint =
(getDecoratedRight(child) + getDecoratedLeft(child)) / 2.f;
float d = Math.min(d1, Math.abs(midpoint - childMidpoint));
float scale = s0 + (s1 - s0) * (d - d0) / (d1 - d0);
child.setScaleX(scale);
child.setScaleY(scale);
}
return scrolled;
} else {
return 0;
}
}
}
I was testing my app on android,
my app have 1 background image with 2 animations using TextureAtlas
it works fine on desctop, the sprite and the animations all scale but when I teste it on android, the sprite resize corretly but the animations dont resize at all
constantes.VIRTUAL_WIDTH=1920;
constantes.VIRTUAL_HEIGHT=1080;
.....
public static void show() {
camera = new OrthographicCamera(constantes.VIRTUAL_WIDTH, constantes.VIRTUAL_HEIGHT); //Aspect Ratio Maintenance
batch = new SpriteBatch();
texturafundo = new Texture("cenarios/penhasco.jpg");
spriteFundo = new Sprite(texturafundo);
spriteFundo.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
// animations
textureAtlas = new TextureAtlas(Gdx.files.internal("anima/rio.txt"));
animacao = new Animation(1/10f, textureAtlas.getRegions());
textureAtlas2 = new TextureAtlas(Gdx.files.internal("anima/portal.txt"));
animacao2 = new Animation(1/10f, textureAtlas2.getRegions());
}
public void render(float delta) {
// update camera
camera.update();
// set viewport
Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
(int) viewport.width, (int) viewport.height);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
elapsedTime+=delta;
batch.begin();
spriteFundo.draw(batch);
//sesenha animacao 1
batch.draw(animacao.getKeyFrame(elapsedTime, true), 0, 0);
batch.draw(animacao2.getKeyFrame(elapsedTime, true), 788, 249);
batch.end();
}
public void resize(int width, int height) {
float aspectRatio = (float)width/(float)height;
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
if(aspectRatio > constantes.ASPECT_RATIO) {
scale = (float) height / (float) constantes.VIRTUAL_HEIGHT;
crop.x = (width - constantes.VIRTUAL_WIDTH * scale) / 2f;
} else if(aspectRatio < constantes.ASPECT_RATIO) {
scale = (float) width / (float) constantes.VIRTUAL_WIDTH;
crop.y = (height - constantes.VIRTUAL_HEIGHT * scale) / 2f;
} else {
scale = (float) width / (float) constantes.VIRTUAL_WIDTH;
}
float w = (float) constantes.VIRTUAL_WIDTH * scale;
float h = (float) constantes.VIRTUAL_HEIGHT * scale;
viewport = new Rectangle(crop.x, crop.y, w, h);
}
Am trying to get the stroke data when the user scribbles on screen and redraw that same stroke on same location, in reduced size based on screen size of display. My issue is that this code works, it scales down striker but all scaled down strokes are connected which I don't want to be.
My ontouch code snippet:
#Override
public boolean onTouch(View arg0, final MotionEvent event) {
x = event.getX();
y =event.getY();
/* float x=(float) (xx*0.7);
float y=(float) (yy*0.7);*/
array_x.add(x);
array_y.add(y);
if(event.getPointerCount() == 2){
timevar2 = event.getEventTime();
float newx = event.getX(0);
float newy = event.getY(0);
float oldx = event.getX(1);
float oldy = event.getY(1);
mPath.reset();
float equa = (float) (Math.pow(newx - oldx, 2) + Math.pow(newy - oldy, 2));
float cscale = (float) Math.sqrt(equa)/100;
float scaled = (cscale - old_scale);
if(scaled < -0.1){
if(scale > 0.1){
scale -= 0.03;
}
}
if(scaled > 0.1){
scale += 0.03;
}
old_scale = cscale;
invalidate();
return true;
}
long dt = event.getEventTime() - timevar2;
if(dt < 100){
return true;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
Log.v("TOUCH=======start","X=="+x + "Y=="+y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
Log.v("TOUCH=======move","X=="+x + "Y=="+y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up(x,y);
Log.v("TOUCH=======up","X=="+x + "Y=="+y);
//invalidate();
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
public void run() {
for(int i=0;i<array_x.size();i++)
{
x= array_x.get(i);
y= array_y.get(i);
if(i == 0){
x=(float) (x*0.7);
y=(float) (x*0.7);
Log.i("ARRAYYYYYY", "X=="+x+"Y=="+y);
touch_start(x, y);
invalidate();
}else if(i == array_x.size()-1){
x=(float) (x*0.7);
y=(float) (x*0.7);
touch_up(x, y);
invalidate();
mPath.reset();
}else{
x=(float) (x*0.7);
y=(float) (y*0.7);
touch_move(x, y);
invalidate();
}
}
}
}, 2000);
break;
}
return true;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
if (this.isErase) {
erasePath(mPath, x, y, mX, mY);
return;
}
PointF point = new PointF();
point.x = x;
point.y = y;
newPoint.points.add(point);
mCanvas.drawPath(mPath, mPaint);
}
private void touch_start(float x, float y) {
undonePaths.clear();
mPath = new Path();
newPoint = new Stroke();
PointF point = new PointF();
point.x = x;
point.y = y;
newPoint.points.add(point);
mCanvas.drawPath(mPath, mPaint);
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_up(float x, float y) {
if (this.isErase) {
return;
}
PointF point = new PointF();
point.x = x;
point.y = y;
newPoint.points.add(point);
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
Pair p = new Pair(mPath, newPoint);
this.Strokepaths.add(p);
}
In Objective C, I am using a function to centre some buttons, which works fine.
The buttons centre perfectly on the screen.
However, converting the code to swift it isn't working as expected. There is extra space on the left hand side:
func centerImageViews()
// Measure the total width taken by the buttons
var width:CGFloat = 0.0
for (index, item) in enumerate(self.soundBoxes) {
if(item.tag>=numberOfBoxes){
item.alpha=0
}else{
item.alpha=1
width += item.bounds.size.width + 10
}
if (width > 10){
width -= 10;
}
// If the buttons width is shorter than the visible bounds, adjust origin
var origin:CGFloat = 0;
if (width < self.view.frame.size.width){
origin = (self.view.frame.size.width - width) / 2.0;
}
// Place buttons
var x:CGFloat = origin;
var y:CGFloat = 200;
for (index, item) in enumerate(self.soundBoxes) {
item.center = CGPointMake(x + item.bounds.size.width/2.0, y + item.bounds.size.height/2.0);
x += item.bounds.size.width + 10;
}
}
}
In Objective C:
- (void)centerImageViews:(NSArray*)imageViews withCount:(int)number
{
int kButtonSeperator=10;
// Measure The Total Width Of Our Buttons
CGFloat width = 0;
for (UIImageView* hit in soundBoxes)
if (hit.tag>=numberOfBoxes) {
hit.alpha=0;
} else {
width += hit.bounds.size.width + kButtonSeperator;
hit.alpha=1;
}
if (width > kButtonSeperator)
width -= kButtonSeperator;
CGFloat origin = 0;
if (width < self.view.frame.size.width)
origin = (self.view.frame.size.width - width) / 2.f;
CGFloat x = origin;
CGFloat y = 85;
UIImageView* hit;
for (hit in imageViews) {
hit.center = CGPointMake(x + hit.bounds.size.width/2.f, y + hit.bounds.size.height/2.f);
//NSLog(#"X Is %f",hit.center.x);
x += hit.bounds.size.width + kButtonSeperator;
}
}
}
Alas this is a university type question, but one im struggling with none the less.
I need to generate large test sets of rectangles, non-overlapping, that can then be used to test an algorithm that finds the adjacencies between them. The test sets will need to probably have upwards of 10000 - 100000 rectangles in them. Ive been searching the net for examples of how to generate test sets like this, but have come up with nothing. Im aware that I could use a purely brute force method, and every time a random rectangle is generated, check whether or not it overlaps with any of the other rectangles, but this seems like generating the test sets will end up taking days if not longer!
Any one know how to go about doing this, or at least where I should start looking?
I found your idea fun and challanging and therefore tried a solution by using a matrix.
Basicly, the idea is (when talking in pixels) to create a matrix of booleans of the same width and height as the square root of MaxWidthOfRectangle * (NumberOfRectangles) (just for simplicity the same width and height).
Next, for each entry in the matrix, generate a random rectangle between min and max bounds. and set all the bools in the matrix for the specific rectangle. Now when generating the next rectangle, you can simply check "around" the desired location to determine how much space you can occupy rather then having to estimate a size and compare with each other rectangle if it conflicts.
My code:
class RectangleGenerator
{
readonly bool[,] _matrix;
readonly int _size;
readonly int _minimalBoxSize;
readonly int _maximumBoxSize;
readonly Random _random = new Random(1);
readonly List<Point> _offsets;
public bool[,] Matrix { get { return _matrix; } }
public RectangleGenerator(int size, int minimalBoxSize, int maximumBoxSize)
{
_matrix = new bool[size, size];
_size = size;
_minimalBoxSize = minimalBoxSize;
_maximumBoxSize = maximumBoxSize;
_offsets = new List<Point>(size * size);
Reset();
}
public IEnumerable<Rectangle> Calculate()
{
while (_offsets.Count > 0)
{
Point currentPoint = _offsets[_offsets.Count - 1];
_offsets.RemoveAt(_offsets.Count - 1);
if (!_matrix[currentPoint.X, currentPoint.Y])
{
Rectangle rectangle;
if (TryCreateNextRectangle(currentPoint.X, currentPoint.Y, out rectangle))
{
// fill the matrix with the rectangle + padding
int startFillX = Math.Max(0, rectangle.Left);
int startFillY = Math.Max(0, rectangle.Top);
int endFillX = Math.Min(_size, rectangle.Right);
int endFillY = Math.Min(_size, rectangle.Bottom);
for (int fillX = startFillX; fillX < endFillX; fillX++)
for (int fillY = startFillY; fillY < endFillY; fillY++)
{
_matrix[fillX, fillY] = true;
}
yield return rectangle;
}
}
}
}
private bool TryCreateNextRectangle(int x, int y, out Rectangle rectangle)
{
int maxWidth = DetermineMaxWidth(x, y, _minimalBoxSize);
int maxHeight = DetermineMaxHeight(y, x, maxWidth);
if (maxWidth < _minimalBoxSize || maxHeight < _minimalBoxSize)
{
rectangle = Rectangle.Empty;
return false;
}
int width = _random.Next(_minimalBoxSize, maxWidth);
int height = _random.Next(_minimalBoxSize, maxHeight);
rectangle = new Rectangle(x, y, width, height);
return true;
}
private int DetermineMaxWidth(int x, int y, int height)
{
int result = Math.Min(_maximumBoxSize, _size - x);
for (int offsetX = 0; offsetX < result; offsetX++)
for (int offsetY = 0; offsetY < height; offsetY++)
{
if (_matrix[x + offsetX, y + offsetY])
{
result = offsetX;
break;
}
}
return result;
}
private int DetermineMaxHeight(int y, int x, int width)
{
int result = Math.Min(_maximumBoxSize, _size - y);
for (int offsetY = 0; offsetY < result; offsetY++)
for (int offsetX = 0; offsetX < width; offsetX++ )
{
if (_matrix[x + offsetX, y + offsetY])
{
result = offsetY;
break;
}
}
return result;
}
public void Reset()
{
// append for padding:
for (int x = 0; x < _size; x++)
for (int y = 0; y < _size; y++)
{
_matrix[x, y] = false;
if (_size - x >= _minimalBoxSize && _size - y >= _minimalBoxSize)
{
_offsets.Add(new Point(x, y));
}
}
_offsets.Sort((x, y) => x == y ? 0 : _random.Next(-1, 1));
}
}