Dynamically change size of GridView - java

I'm developing an application for android, and i have a big old GridView that's centered vertically in the screen, with all the cells visible.
What i want, is a function by which all cells are zoomed in by a factor of 3, letting the user scroll around in the gridview instead.
Sort of how Wordfeud does it if you're familiar with the game.
I've searched the webs and haven't found a satisfactory solution, i managed to find a way to alter the layout params in my adapter for the grid tiles, but it only stretches them vertically and not horizontally, also the whole app becomes slow and unresponsive until you've scrolled through the list and let the Grid reload all the views or whatever.
Any help at all is appreciated.

In the end, i used a custom view with a Canvas instead - much easier than trying to bend GridView into something it's not supposed to be.

I know it's been a while since you asked, but I had a similar problem that it took me a long time to solve, so I'm hoping someone else may stumble on this. I ended up extending the GridLayout class and hooking up an instance of
private class ScaleGestureListener
extends ScaleGestureDetector.SimpleOnScaleGestureListener
in the constructor:
scaleDetector = new ScaleGestureDetector(context, new ScaleGestureListener());
since it's a view group, override the dispatch… instead of the on… methods:
#Override
public boolean dispatchTouchEvent(MotionEvent ev){
scaleDetector.onTouchEvent(ev);
super.dispatchTouchEvent(ev);
return true;
}
#Override
public void dispatchDraw(Canvas canvas) {
String disp = String.valueOf(mScaleFactor);
Log.v(TAG, "dispatch draw " + disp);
canvas.save();
// i have some other stuff in here specific to my app
canvas.scale(mScaleFactor, mScaleFactor);
super.dispatchDraw(canvas);
canvas.restore();
}

Related

LibGDX making viewport larger than screen

I've been struggling with how to use and set up Viewports in LibGDX for quite some time. I want to be able to render everything like its on a display that is 1920x1080 and have it scale to fit the display its on, and I need some help getting to work like that.
This is what I want it to look like (taken from a computer with a 1920x1080 monitor), but when I run the same code on my laptop which is 1440x800, it looks like this. I apologize for the poor photo of a screen, I couldn't get it to take a screenshot of the game running for whatever reason, but it shows that the top of the display remains unused, and that not everything is being fit to the display. This is the main code running the show:
public class Main extends Game {
...
public void create() {
...
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
//last
this.setScreen(new MainMenu(this));
}
public void render() {
super.render(); //important!
}
...
}
And then the MainMenu class
public class MainMenu implements Screen{
...
public MainMenu(final Main game) {
this.game = game;
cam = new OrthographicCamera();
cam.setToOrtho(false, 1920, 1080);
...
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.025f, .025f, 0.025f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.update();
game.batch.setProjectionMatrix(cam.combined);
...
if(Gdx.input.isKeyPressed(Keys.ESCAPE)) {
Gdx.app.exit();
}
}
...
}
How would I implement a Viewport or something of the like to get it to look the same on the smaller screen as it does on the larger? Any help is really appreciated! If you want to see the code that I left out for brevity, its all on my GitHub. Thanks again!
That didn't take me long, hopefully someone will learn from me though, ha ha.
Turns out when you use the camera with fixed height and width like that, it does fill up the whole monitor, but the cameras width DOES NOT equal the value returned by Gdx.graphics.getWidth(). Because of this all my code was rendering like it was being compressed because it was referencing the width returned by Gdx.graphics, and not the camera.viewportWidth.
Lesson learned: Gdx.graphics.getWidth() can and will change depending on device and cam.veiwportWidth wont. Oops!

JavaFx Stop Moving Image Smudging Canvas

I'm trying to make a simple animated menu with images bouncing off around the screen but the images leave a trail where ever the move.
public void handle(long now) {
// TODO Auto-generated method stub
boolean intersectFlag = false;
for(Letter l : letters){
gameMenuGraphicsContext.drawImage(l.letterImage, l.letterRectangle.getX(), l.letterRectangle.getY());
l.moveSimple();
}
}};
Any idea on how to stop this happening?
Think of the Canvas as a piece of paper onto which you are writing. If you don't erase anything explicitly everything will be visible what you have ever drawn to it. Actually you should reconsider your decision to use a Canvas at all. It is not very well suited for such kind of animations.
As mipa stated, your problem is that the drawn image is never erased. To erase your canvas, use:
graphicsContext.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
To keep yourself from having to call the clearRectmethod each time you want to draw on the screen, one easy write-and-forget way is to combine the clearing and drawing into one method. You can even use a lambda expression to draw on the canvas, as in the following code:
private static void clearAndDraw(GraphicsContext gc, Consumer<GraphicsContext> draw) {
gc.clearRect(0, 0, gc.getCanvas().getWidth(), gc.getCanvas().getHeight());
draw.accept(gc);
}
public void handle(long now) {
//...
for(Letter l : letters) {
clearAndDraw(graphicsContext, gc -> gc.drawImage(l.letterImage, l.letterRectangle.getX(), l.letterRectangle.getY()));
//...
}
}

Antialias on clipPath on layout

I have a layout, which has several views inside of it - toolbar, recyclerview and few separators (which are simple views with height of 2dp and match_parent width). I wanted to put a mask on a layout - most important part of it are the round corners for whole layout (and not the views itself). I decided to create my own LinearLayout class with overloaded dispatchDraw function and I managed to get nice result... except for one thing - those corners are not antialiased.
tl;dr is there ANY way to put antialias to clipPath function? I know can turn it on in Paint and then use xfermodes to mask the layout, however I have no clue how to draw mask and then draw everything else (without knowing what's exactly inside).
Here is my layout code (except for classname, simple constructors and Path field):
#Override protected void dispatchDraw(Canvas canvas) {
if (path == null) {
path = new Path();
float margin = MyApplication.getInstance().getMetrics().density * 5;
path.addRoundRect(new RectF(margin,margin,getWidth()-margin, getHeight()-margin),
margin*2, margin*2, Path.Direction.CW);
}
canvas.clipPath(path);
super.dispatchDraw(canvas);
}
#Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
try this SO answer, of course instead of mMask.draw(canvas) which is a "mask" made by a NinePatchDrawable you would need to call canvas.drawPath() with a Paint set with PorterDuff.Mode.DST_IN xfer mode

Android horizontal text scroll - automatic and by gesture

I'm relatively new to Android programming, and I need a control that holds text and scrolls automatically. Now, I know about the "marquee" in the TextView control and it works fine for what it's intended, but that approach has two problems.
1) I need the text to scroll regardless of its length, i.e. if the text is only "Hello", and the control is set to match parents width, it needs to scroll.
2) The control needs to respond to user scroll - by flicking/dragging it left/right, the text should also scroll.
And naturally, when the text is "gone" to the left side, it should reappear on the right side and continue scrolling. For now, it should be a single line text.
Does anything like that exist, and if not, what would be the best approach guidelines to implementing it?
I ended up extending the default TextView, and pulling out Marquee class from TextView source. From there it's easy to modify the Marquee class so that it starts/stops when needed, and no longer requires the TextView to be selected (if that requirement is necessary).
To implement slide by gesture, the base class implements OnGestureListener and in onScroll(...) I update the offset in Marquee class, so when the View is drawn the next time it applies the new scroll offset.
And finally, to actually scroll by the amount needed, in the constructor I set the custom scroller, and in onDraw apply the scroll.
The important parts of code:
public class MarqueeTextView extends TextView implements OnGestureListener {
private GestureDetector gestureDetector;
private Marquee marquee;
private Scroller scroller;
// constructor
public MarqueeTextView(Context context, AttributeSet attrs) {
this.marquee = new Marquee(this);
this.scroller = new Scroller(context);
this.setScroller(scroller);
gestureDetector = new GestureDetector(getContext(), this);
// when enabled, longpress disables further movement tracking
gestureDetector.setIsLongpressEnabled(false);
}
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
marquee.addToScroll(distanceX);
return false;
}
// onDraw
protected void onDraw(Canvas canvas) {
scroller.setFinalX((int) marquee.mScroll);
super.onDraw(canvas);
}
// Marquee handler
private static final class Marquee extends Handler {
// mostly the same as original
// ...
float mScroll;
public void addToScroll(float amount) {
mScroll += amount;
// detect if needs to start over
}
}
}

Draw Dynamic Shapes

I need some help to make an activity.
I have stored coordinates from shapes and name of shapes in a database. These are grouped into rooms.
In the activity I need the top of the screen 8 TextViews (with colors and textst) in two rows. If I click on a textView, accordingly the shapes for the room need to be drawn on the screen under the textViews.
If I click on a shape, I need to get back the information, on which shape I made a click.
I guess you could create a custom view:
public class CustomView extends View { ... }
and then you simply override appropriate methods like:
#Override
public boolean onTouchEvent(MotionEvent ev) { /* check for hitting shapes here */ }
#Override
protected void onDraw(Canvas canvas) { /* draw anything you want here */ }
Use the search engine of your choice to find out more. This looks like what you need

Categories