Categories
discuss

How to remove specific activity from the stack

Lets put we 3 activates that may follow the stack A->B->C

How can I close A and keep B->C, but only if B opens C?

C is not always opened, but if it gets opened only then A should be removed, leaving the stack as B->C. Otherwise will remain as A->B.

I don’t see the possibility of using finish() in A, as it should be closed from B when opening C.

By the way A is a single instance with its own affinity.

Answer

Write an abstract BaseActivity class and implement a LocalBroadcastManager in it and register a BroadcastReceiver. Note that we have also introduced an abstract onFinishReceived method.

public abstract class BaseActivity extends AppCompatActivity {

  private LocalBroadcastManager mLBM;
  private final BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      onFinishReceived(intent.getStringExtra("activity"));
    }
  }

  protected void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    mLBM = LocalBroadcastManager.getInstance(this);
    IntentFilter filter = new IntentFilter();
    filter.addAction(...);
    mLBM.registerReceiver(receiver, filter);
  }

  protected void onDestroy() {
    mLBM.unregisterReceiver(receiver);
    mLBM = null;
  }

  abstract void onFinishReceived(String activity);
}

Then, extend all A, B and C Activities from the BaseActivity and override the onFinishReceived() method.

public class A extends BaseActivity {

  void onFinishReceived(String activity) {
    if (activity.equals("A") { // or "B" or "C"
        finish();
      }
    }
  }
}

Now, whenever you want to finish a specific activity use,

LocalBroadcastManager.getInstance(context)
    .sendBroadcast(new Intent()
        .setAction(...)
        .putExtra("activity", "A") // or "B" or "C"
    );

LocalBroadcastManager is now deprecated. It’s better if you can use something like RxJava. The idea is to use an asynchronous and event-based mechanism rather than going for a simple ugly solution like storing the Activity in a static variable.

Categories
discuss

React routing using components (PageRenderer)

what I’m trying to do is basic routing in React. Usually what I have done and what I will mention later on is use element={}. But currently I want to learn and experiment what other options there are so I came across components where you insert a function. I have followed a tutorial and I did the exact same besides he uses older version of router dom so he doesent use Routes.

Here is the code:

App.js:

import {BrowserRouter as Router, Routes, Route} from 'react-router-dom'

import Register from './pages/register';
import Login from './pages/login';
import PageRender from './PageRender';

function App() {
  return (
    <Router>
      <input type='checkbox' id='theme'/>
      <div className="App">
        <div className="main"> 
        <Routes> 
          <Route exact path="/:page" component={PageRender}/>
          <Route exact path="/:page/:id" component={PageRender}/>
        </Routes>
        </div>
      </div>
    </Router>
  );
}

export default App;

PageRender.js:

import React from 'react'
import { useParams } from 'react-router'
import NotFound from './components/NotFound'

const generatePage = (pageName) => {
    const component = () => require(`./pages/${pageName}`).default

    try {
        return React.createElement(component())
    } catch (err) {
        return <NotFound />
    }
}


const PageRender = () => {
    const {page, id} = useParams()
    let pageName = "";

    if(id){
        pageName = `${page}/[id]`
    }else{
        pageName = `${page}`
    }

    return generatePage(pageName)
}

export default PageRender

The login and register js are just basic arrow functions which display login or register (still didnt come to that part). What I want to do is when i enter the url lets say for instance: http://localhost:3000/register it sends me to register page and if I enter a wrong path it will send me to NotFound page. But sadly it doesent work. I know the workaround this problem if I simply do this:

<Route exact path="/login" element={<Login/>}/>

And yeah this method works but currently Im in process of learning and Im currious why this method didnt work. So any helpful tips, tricks and method would be great. Looking forward to hear your responses, thanks in advance 😀

Answer

I was able to get your code working in react-router-dom v5, the trick was importing the components once in App so they are built/transpiled. The PageRender component worked as-is.

RRDv5

import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";

import './pages/register';
import "./pages/login";
import PageRender from "./PageRender";

export default function App() {
  return (
    <Router>
      <input type="checkbox" id="theme" />
      <div className="App">
        <div className="main">
          <Switch>
            <Route path="/:page/:id" component={PageRender} />
            <Route path="/:page" component={PageRender} />
          </Switch>
        </div>
      </div>
    </Router>
  );
}

RRDv6 – Swap the Switch component to the Routes component, and switch to using the element prop instead of the component prop to render the PageRender component as JSX.

import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";

import './pages/register';
import "./pages/login";
import PageRender from "./PageRender";

export default function App() {
  return (
    <Router>
      <input type="checkbox" id="theme" />
      <div className="App">
        <div className="main">
          <Routes>
            <Route path="/:page/:id" element={<PageRender />} />
            <Route path="/:page" element={<PageRender />} />
          </Routes>
        </div>
      </div>
    </Router>
  );
}

Edit react-routing-using-components-pagerenderer

Categories
discuss

MPAndroidChart – How to display text to the left of LimitLine?

I’m trying to display text on the left of the LimitLine like this:

enter image description here

However these are the only options I’m getting for setting the position of the Label for limit line.

enter image description here

I’m using LimitLine.LimitLabelPosition.LEFT_TOP and it only displays the Label above the Limit line.

enter image description here

YAxis leftAxis = mChart.getAxisLeft();
LimitLine minimumLimit = new LimitLine(50f, "Minimum Limit");
minimumLimit.setLineWidth(0.5f);
minimumLimit.setTextColor(ContextCompat.getColor(this, R.color.white_60_opacity));
minimumLimit.setLabelPosition(LimitLine.LimitLabelPosition.LEFT_TOP);
leftAxis.addLimitLine(minimumLimit);

How do I display the LimitLine‘s Label to the left of the LimitLine?

Edit:

I have also tried used the methods .setXOffset(50f) and .setYOffset(50f) but this only shifts the position of the label and not the line minimumLimit.

enter image description here

Answer

You can achieve this by using a custom YAxisRenderer with a little modification of the override method public void renderLimitLines(Canvas c).

The modifications needed for this purpose are:

1.To calculate the label width of each limit line to be able to move the limit line to the correct x position like below:

limitLinePath.moveTo(mViewPortHandler.contentLeft()+getLabelTextWidth(l), pts[1]);

2.To draw the label to the new x,y position something like this:

c.drawText(label, mViewPortHandler.contentLeft() + xOffset, pts[1]+l.getYOffset(), mLimitLinePaint);

Below is a custom MyYAxisRenderer containing the above modifications:

public class MyYAxisRenderer extends YAxisRenderer {

    private final Paint textPaint;

    public MyYAxisRenderer(ViewPortHandler viewPortHandler, YAxis yAxis, Transformer trans) {
        super(viewPortHandler, yAxis, trans);
        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    @Override
    public void renderLimitLines(Canvas c) {

        List<LimitLine> limitLines = mYAxis.getLimitLines();

        if (limitLines == null || limitLines.size() <= 0)
            return;

        float[] pts = mRenderLimitLinesBuffer;
        pts[0] = 0;
        pts[1] = 0;
        Path limitLinePath = mRenderLimitLines;
        limitLinePath.reset();

        for (int i = 0; i < limitLines.size(); i++) {

            LimitLine l = limitLines.get(i);

            if (!l.isEnabled())
                continue;

            int clipRestoreCount = c.save();
            mLimitLineClippingRect.set(mViewPortHandler.getContentRect());
            mLimitLineClippingRect.inset(0.f, -l.getLineWidth());
            c.clipRect(mLimitLineClippingRect);

            mLimitLinePaint.setStyle(Paint.Style.STROKE);
            mLimitLinePaint.setColor(l.getLineColor());
            mLimitLinePaint.setStrokeWidth(l.getLineWidth());
            mLimitLinePaint.setPathEffect(l.getDashPathEffect());

            pts[1] = l.getLimit();

            mTrans.pointValuesToPixel(pts);

            limitLinePath.moveTo(mViewPortHandler.contentLeft()+getLabelTextWidth(l), pts[1]);
            limitLinePath.lineTo(mViewPortHandler.contentRight(), pts[1]);

            c.drawPath(limitLinePath, mLimitLinePaint);
            limitLinePath.reset();

            String label = l.getLabel();

            // if drawing the limit-value label is enabled
            if (label != null && !label.equals("")) {

                mLimitLinePaint.setStyle(l.getTextStyle());
                mLimitLinePaint.setPathEffect(null);
                mLimitLinePaint.setColor(l.getTextColor());
                mLimitLinePaint.setTypeface(l.getTypeface());
                mLimitLinePaint.setStrokeWidth(0.5f);
                mLimitLinePaint.setTextSize(l.getTextSize());

                final float labelLineHeight = Utils.calcTextHeight(mLimitLinePaint, label);
                float xOffset = getLimitLineXOffset(l);
                float yOffset = l.getLineWidth() + labelLineHeight + l.getYOffset();

                final LimitLine.LimitLabelPosition position = l.getLabelPosition();

                //draw the label on the left in the same y position of the limit line
                mLimitLinePaint.setTextAlign(Paint.Align.LEFT);
                c.drawText(label,
                        mViewPortHandler.contentLeft() + xOffset,
                        pts[1]+l.getYOffset(), mLimitLinePaint);
            }

            c.restoreToCount(clipRestoreCount);
        }
    }

    private float getLimitLineXOffset(LimitLine l){
        return Utils.convertDpToPixel(4f) + l.getXOffset();
    }

    private float getLabelTextWidth(LimitLine l) {

        String label = l.getLabel();
        if (label != null && !label.equals("")) {

            textPaint.setStyle(l.getTextStyle());
            textPaint.setPathEffect(null);
            textPaint.setColor(l.getTextColor());
            textPaint.setTypeface(l.getTypeface());
            textPaint.setStrokeWidth(0.5f);
            textPaint.setTextSize(l.getTextSize());

            int textWidth = Utils.calcTextWidth(textPaint, label);
            float xOffset = getLimitLineXOffset(l);

            return textWidth + (xOffset*2);
        }
        return 0;
    }
}

In the above renderer i have added two helper functions one for the calculation of the label text width private float getLabelTextWidth(LimitLine l) for a specific limit line and one to get the x offset of each limit line private float getLimitLineXOffset(LimitLine l) which you can modify based on your needs.

And you can use the above Renderer like the below:

lineChart.setRendererLeftYAxis(new MyYAxisRenderer(lineChart.getViewPortHandler(), lineChart.getAxisLeft(), lineChart.getTransformer(YAxis.AxisDependency.LEFT)));

Result:

limit_lines

Note: This was tested with v3.1.0 (‘com.github.PhilJay:MPAndroidChart:v3.1.0’)

Categories
discuss

Matter.Query.region not returning any collisions even though the bound is clearly intersecting other bodies

I’m trying to use Matter.Query.region to see if the character in my game is grounded. But, when I try to run region with a bounds object that I created (displayed with the dots shown in the game), it doesn’t come up with any collisions even though it is clearly intersecting other bodies.

Code:

let Engine = Matter.Engine,
    Runner = Matter.Runner,
    World = Matter.World,
    Bodies = Matter.Bodies,
    Body = Matter.Body,
    Composite = Matter.Composite;

let engine;

let boxA;
let boxB;
let platforms = [];

function setup() {
  createCanvas(550, 400);

  // create an engine
  engine = Engine.create();

  // create two boxes and a ground
  boxA = Bodies.rectangle(275, 200, 80, 80, {
    mass: 20
  });
  platforms.push(boxA);

  boxB = Bodies.rectangle(300, 50, 80, 80, {
    mass: 20
  });
  Body.setInertia(boxB, Infinity);
  
  ground = Bodies.rectangle(250, 410, 810, 60, {
    isStatic: true
  });
  platforms.push(ground);

  // add all of the bodies to the world
  World.add(engine.world, [boxA, boxB, ground]);

  let runner = Runner.create();
  Runner.run(runner, engine);
}

// Using p5 to render
function draw() {
  let add = Matter.Vector.add; // alias

  let leeway = {x: 0, y: 30}
  let topLeft = {x: boxB.position.x - 40, y: boxB.position.y + 40}
  let topRight = add(topLeft, {x: 80, y: 0});
  let bottomLeft = add(topLeft, leeway);
  let bottomRight = add(topRight, leeway);

  let bounds = Matter.Bounds.create(topLeft, topRight, bottomRight, bottomLeft);
  let query = Matter.Query.region(platforms, bounds);
  
  console.log(Matter.Bounds.overlaps(bounds, boxA.bounds), query);

  background(51);
  keyDown();
  
  drawShape(boxA);
  drawShape(boxB);
  drawShape(ground, 127);

  push();
  // Show bounds
  stroke('purple');
  strokeWeight(10);
  point(topLeft.x, topLeft.y);
  point(topRight.x, topRight.y);
  point(bottomLeft.x, bottomLeft.y);
  point(bottomRight.x, bottomRight.y);
  pop();
}

function drawShape(body, color = 225) {
  beginShape();
  fill(color);
  for (let vertice of body.vertices) {
    vertex(vertice.x, vertice.y);
  }
  endShape();
}

function keyPressed() {
  let jumpHeight = 14;
  
  if (keyCode === UP_ARROW) {
    Body.setVelocity(boxB, {x:boxB.velocity.x, y:-jumpHeight})
  }
}
function keyDown() {
  let velocity = 12;
  let targetX = boxB.velocity.x;

  if (keyIsDown(RIGHT_ARROW)) {
    targetX = velocity;
  } else if (keyIsDown(LEFT_ARROW)) {
    targetX = -velocity;
  } else {
    targetX = 0;
  }
  targetX = lerp(boxB.velocity.x, targetX, 0.1);
  Body.setVelocity(boxB, {x: targetX, y: boxB.velocity.y});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js" integrity="sha512-5T245ZTH0m0RfONiFm2NF0zcYcmAuNzcGyPSQ18j8Bs5Pbfhp5HP1hosrR8XRt5M3kSRqzjNMYpm2+it/AUX/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Full code: https://replit.com/@CrazyVideoGamer/MatterQueryregion-not-working#sketch.js

By the way, the character is the variable boxB, and you can move with the arrow keys.

Answer

The bounds object doesn’t appear to be properly created. The purple p5 vertices you’re rendering may be giving you a false sense of confidence, since those aren’t necessarily related to what MJS sees.

It’s actually a pretty simple fix, passing an array of vertices instead of individual arguments:

let bounds = Matter.Bounds.create([topLeft, topRight, bottomRight, bottomLeft]);
//                                ^                                          ^

I wound up cleaning things up a bit in the process of debugging and made the collision easier to visualize without the console. Feel free to use some of this code if you need or just make the one change as you see fit.

const {Engine, Runner, World, Bodies, Body} = Matter;
let engine;
let boxA;
let boxB;
const platforms = [];

function setup() {
  createCanvas(550, 400);
  engine = Engine.create();

  // create two boxes and a ground
  boxA = Bodies.rectangle(275, 200, 80, 80, {
    mass: 20
  });
  platforms.push(boxA);

  boxB = Bodies.rectangle(300, 50, 80, 80, {
    mass: 20
  });
  Body.setInertia(boxB, Infinity); // TODO remove for realism
  
  ground = Bodies.rectangle(250, 410, 810, 60, {
    isStatic: true
  });
  platforms.push(ground);
  World.add(engine.world, [boxA, boxB, ground]);
  Runner.run(Runner.create(), engine);
}

function draw() {
  const {x, y} = boxB.position;
  const vertices = [
    // FIXME hardcoded values for now...
    {x: x - 40, y: y + 40},
    {x: x + 40, y: y + 40},
    {x: x + 40, y: y + 50},
    {x: x - 40, y: y + 50},
  ];
  const bounds = Matter.Bounds.create(vertices, boxB);
  
  // return valaue holds the collided platform(s)
  const collisions = Matter.Query.region(platforms, bounds);

  background(51);
  keyDown();
  
  drawShape(boxA);
  drawShape(boxB);
  drawShape(ground, 127);

  push();
  // Show bounds collision
  stroke(collisions.length ? 'red' : 'purple');
  strokeWeight(10);
  vertices.forEach(({x, y}) => point(x, y));
  pop();
}

function drawShape(body, color=225) {
  beginShape();
  fill(color);
  body.vertices.forEach(({x, y}) => vertex(x,  y));
  endShape();
}

function keyPressed() {
  const jumpHeight = 14;
  
  if (keyCode === UP_ARROW) {
    Body.setVelocity(boxB, {x: boxB.velocity.x, y: -jumpHeight})
  }
}

function keyDown() {
  const velocity = 12;
  let targetX = 0;

  if (keyIsDown(RIGHT_ARROW)) {
    targetX = velocity;
  } else if (keyIsDown(LEFT_ARROW)) {
    targetX = -velocity;
  }
  
  targetX = lerp(boxB.velocity.x, targetX, 0.1);
  Body.setVelocity(boxB, {x: targetX, y: boxB.velocity.y});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
Categories
discuss

Removing the delay on text animation – HTML/CSS

I have the following code:

/*Vertical Flip*/

.verticalFlip {
  display: inline;
}

.verticalFlip span {
  animation: vertical 5s linear infinite 0s;
  -ms-animation: vertical 5s linear infinite 0s;
  -webkit-animation: vertical 5s linear infinite 0s;
  color: #ea1534;
  opacity: 0;
  overflow: hidden;
  position: absolute;
}

.verticalFlip span:nth-child(2) {
  animation-delay: 2.5s;
  -ms-animation-delay: 2.5s;
  -webkit-animation-delay: 2.5s;
}


/*Vertical Flip Animation*/

@-moz-keyframes vertical {
  0% {
    opacity: 0;
  }
  5% {
    opacity: 0;
    -moz-transform: rotateX(180deg);
  }
  10% {
    opacity: 1;
    -moz-transform: translateY(0px);
  }
  25% {
    opacity: 1;
    -moz-transform: translateY(0px);
  }
  30% {
    opacity: 0;
    -moz-transform: translateY(0px);
  }
  80% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@-webkit-keyframes vertical {
  0% {
    opacity: 0;
  }
  5% {
    opacity: 0;
    -webkit-transform: rotateX(180deg);
  }
  10% {
    opacity: 1;
    -webkit-transform: translateY(0px);
  }
  25% {
    opacity: 1;
    -webkit-transform: translateY(0px);
  }
  30% {
    opacity: 0;
    -webkit-transform: translateY(0px);
  }
  80% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@-ms-keyframes vertical {
  0% {
    opacity: 0;
  }
  5% {
    opacity: 0;
    -ms-transform: rotateX(180deg);
  }
  10% {
    opacity: 1;
    -ms-transform: translateY(0px);
  }
  25% {
    opacity: 1;
    -ms-transform: translateY(0px);
  }
  30% {
    opacity: 0;
    -ms-transform: translateY(0px);
  }
  80% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}


/* text */

#hero h1 {
  margin: 0;
  font-size: 64px;
  font-weight: 700;
  line-height: 56px;
  color: transparent;
  background: url("https://lovelytab.com/wp-content/uploads/2019/01/Tumblr-Aesthetic-Wallpapers-Free.jpg") repeat;
  background-clip: text;
  -webkit-background-clip: text;
}
<section id="hero">
  <h1 style="margin-bottom: 16px">Sample
    <div class="verticalFlip"><span>Change</span><span>Text</span></div>
  </h1>
</section>

This is working fine, however, how can I remove the delay? There is a long pause after the text alternating gets completed. I would like it to be instant where it keeps on alternating the text in a smooth manner. The only thing I would like to remove is the long pause, that is it. I am not sure which css property is causing that issue. Any suggestions?

Answer

You need to play around with the animation duration and also adjust the key frames percentages -> the tween in when you are flipping the text using your transform/opacity rules.

I have slightly adjusted each, but this comes down to a taste in how you want it to look and feel. Spreading the flipping animation over more of a percent (your tween) will lessen the amount of time you have in a pause between animations.

/*Vertical Flip*/

.verticalFlip {
  display: inline;
}

.verticalFlip span {
  animation: vertical 3.4s linear infinite 0s;
  -ms-animation: vertical 3.4s linear infinite 0s;
  -webkit-animation: vertical 3.4s linear infinite 0s;
  color: #ea1534;
  opacity: 0;
  overflow: hidden;
  position: absolute;
}

.verticalFlip span:nth-child(2) {
  animation-delay: 2s;
  -ms-animation-delay: 2s;
  -webkit-animation-delay: 2s;
}


/*Vertical Flip Animation*/

@-moz-keyframes vertical {
  0% {
    opacity: 0;
  }
  15% {
    opacity: 0;
    -moz-transform: rotateX(180deg);
  }
  35% {
    opacity: 1;
    -moz-transform: translateY(0px);
  }
  55% {
    opacity: 1;
    -moz-transform: translateY(0px);
  }
  80% {
    opacity: 0;
    -moz-transform: translateY(0px);
  }
  90% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@-webkit-keyframes vertical {
  0% {
    opacity: 0;
  }
  15% {
    opacity: 0;
    -webkit-transform: rotateX(180deg);
  }
  35% {
    opacity: 1;
    -webkit-transform: translateY(0px);
  }
  55% {
    opacity: 1;
    -webkit-transform: translateY(0px);
  }
  80% {
    opacity: 0;
    -webkit-transform: translateY(0px);
  }
  95% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@-ms-keyframes vertical {
  0% {
    opacity: 0;
  }
  15% {
    opacity: 0;
    -ms-transform: rotateX(180deg);
  }
  35% {
    opacity: 1;
    -ms-transform: translateY(0px);
  }
  55% {
    opacity: 1;
    -ms-transform: translateY(0px);
  }
  80% {
    opacity: 0;
    -ms-transform: translateY(0px);
  }
  95% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}


/* text */

#hero h1 {
  margin: 0;
  font-size: 64px;
  font-weight: 700;
  line-height: 56px;
  color: transparent;
  background: url("https://lovelytab.com/wp-content/uploads/2019/01/Tumblr-Aesthetic-Wallpapers-Free.jpg") repeat;
  background-clip: text;
  -webkit-background-clip: text;
}
<section id="hero">
  <h1 style="margin-bottom: 16px">Sample
    <div class="verticalFlip"><span>Change</span><span>Text</span></div>
  </h1>
</section>
Source: stackoverflow
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

- © No Copyrights, All Questions are retrived from public domain.