Better I put my question as an example
I have the word FREE in a textview
I apply a strikethrough(EXC, EXC) span to the word FREE so I get FREE
Then I insert spaces between the letters and here comes the problem, because I get
F R E E but I want F R E E
It seems it only happens with spaces(I also tried "\u00a0"), because I also tried to insert a normal character (L) and there was no problem, the result was FLRLELE and not FLRLELE.
Any help is appreciated.
Thanks
Are you applying the span character by character, or to the entire substring?
I was having the same problem when I tried the former approach; but when I changed to the latter, it worked perfectly.
Here is an excerpt of the code I used.
The if conditions add a padding of strikethrough around the substrings.
// ↑↑↑ Several layers of loops... :-X
mySubString = textview_Text.substring ( indexStart, indexEnd );
for ( Integer charIndex = 0 ; charIndex < mySubString.length() ; charIndex++ )
{
charOfIndex = String.valueOf ( mySubString.charAt ( charIndex ) );
if ( charIndex > 0 )
{ charOfIndex_Previous = String.valueOf ( mySubString.charAt ( charIndex - 1 ) ); }
else
{ charOfIndex_Previous = charOfIndex; }
if ( charIndex < mySubString.length() - 1 )
{ charOfIndex_Next = String.valueOf ( mySubString.charAt ( charIndex + 1 ) ); }
else
{ charOfIndex_Next = charOfIndex; }
if ( ( charOfIndex.equals ( charSpace ) )
&& ( ! charOfIndex_Next.equals ( charSpace ) ) )
{ spanStart = indexFromPreviousLoop + charIndex; }
if ( ( ! charOfIndex_Previous.equals ( charSpace ) )
&& ( charOfIndex.equals ( charSpace ) ) )
{ spanEnd = indexFromPreviousLoop + charIndex + 1; }
}
mySpannable.setSpan ( new StrikethroughSpan (), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE );
Related
I have one small code i don't know how to do it.
I have Realtime database in firebase,
and i want check if child name is exist or not.
example:
Realtime database:
i tried before this code and the compiler is pass from this code and not execute it or going to check.
mDatabase.child ( "Voted" ).child ( DataTeamVote.name.get ( position ) ).addListenerForSingleValueEvent ( new ValueEventListener ( )
{
#Override
public void onDataChange ( DataSnapshot snapshot )
{
if ( snapshot.hasChild ( mAuth.getCurrentUser ( ).getUid ( ) ) )
{
check = false;
Toast.makeText ( VoteAction.this , "You are already voted for this team" , Toast.LENGTH_SHORT ).show ( );
}
else
{
check = true;
Toast.makeText ( VoteAction.this , "Open Vote" , Toast.LENGTH_SHORT ).show ( );
}
}
#Override
public void onCancelled ( #NonNull DatabaseError databaseError )
{
}
} );
I am utilizing the PhotoView class by Chris Banes to be able to zoom into an image and see it, but I want to make it so that when I change the orientation, the photo will still be zoomed in after the change.
I understand the basics of how to do this, that when an orientation change is detected, onSaveInstanceState will be called, so I'm trying to save the instance in there, and then put it back into the PhotoView when onCreate is called.
public class MainActivity extends ActionBarActivity
{
PhotoView mPhotoView;
#Override
protected void onCreate( Bundle aSavedInstanceState )
{
super.onCreate( aSavedInstanceState );
mPhotoView = new PhotoView(this);
mPhotoView.setMaximumScale( 12 );
setContentView( mPhotoView );
mPhotoView.setImageResource( R.drawable.vm_app_icon);
if (aSavedInstanceState != null)
{
RectF theRect = aSavedInstanceState.getParcelable( "Rect" );
if ( theRect != null)
{
Matrix theMatrix = new Matrix();
theMatrix.setScale( theRect.bottom, theRect.left, theRect.right, theRect.top );
mPhotoView.setDisplayMatrix( theMatrix );
}
}
}
#Override
protected void onSaveInstanceState( final Bundle outState )
{
super.onSaveInstanceState( outState );
RectF theRect = mPhotoView.getDisplayRect();
if (theRect != null)
{
outState.putParcelable( "Rect", theRect );
}
}
}
But this doesn't work. What should I be storing in the bundle to be able to apply back to the PhotoView to keep the zoom level?
Alright after like 10 hours of trying I've figured it out.
To save the zoom level I needed to save two things in the Bundle, the Scale (Zoom level), and the DisplayRect (of type RectF).
Zoom Level - Number between the MinScale and MaxScale, in my instance between 1 and 16
The RectF holds four values, which for some reason are the coordinates of the Top-Left corner of the current view with respect to the current screen orientation. Even though it holds the top-left coordinates I don't want to rotate around that, I want to rotate around the center, so I need to find the center of the rect and then divide that value by the "ScreenBase" which is a value that will standardize the values and will make it able to be translated into a difference plane. Here's how I saved it:
#Override
protected void onSaveInstanceState( final Bundle outState )
{
super.onSaveInstanceState( outState );
Matrix theMatrix = mPhotoView.getDisplayMatrix();
float[] theFloat = new float[9];
theMatrix.getValues( theFloat );
RectF theRect = mPhotoView.getDisplayRect();
if (theRect != null)
{
if( theRect.left > ( mViewWidth / 2 ) || ( theRect.left >= 0 ) )
{
theRect.left = 0;
}
else
{
theRect.left = ( theRect.left - ( mViewWidth / 2 ) ) / mScreenBase;
}
if( theRect.top > ( mViewHeight / 2 ) || ( theRect.top >= 0 ) )
{
theRect.top = 0;
}
else
{
theRect.top = ( theRect.top - ( mViewHeight / 2 ) ) / mScreenBase;
}
outState.putParcelable( "RectF", theRect );
outState.putFloat( "ZoomLevel", mPhotoView.getScale() );
}
}
Then when we pick it up on the other side, we have to do a lot of manipulation to the numbers to get the top left corner of the new screen space centered around the same place (and manipulate it if an boundary problem occurs), here's how I did it:
#Override
protected void onCreate( final Bundle aSavedInstanceState )
{
super.onCreate( aSavedInstanceState );
mPhotoView = new PhotoView( this );
mPhotoView.setMaximumScale( 16 );
setContentView( mPhotoView );
mPhotoView.setImageResource( R.drawable.vm_app_icon );
mPhotoView.getViewTreeObserver().addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener()
{
public boolean onPreDraw()
{
mPhotoView.getViewTreeObserver().removeOnPreDrawListener( this );
mViewHeight = mPhotoView.getMeasuredHeight();
mViewWidth = mPhotoView.getMeasuredWidth();
Matrix theMatrix = mPhotoView.getDisplayMatrix();
theMatrix.getValues( mBaseMatrixValues );
mScreenBase = mBaseMatrixValues[ 0 ];
int theWidth = mPhotoView.getWidth();
Log.e(TAG, theWidth + "");
if( aSavedInstanceState != null )
{
float[] theFloats = new float[ 9 ];
float theZoom = aSavedInstanceState.getFloat( "ZoomLevel" );
RectF theRect = aSavedInstanceState.getParcelable( "RectF" );
theFloats[ 0 ] = theZoom;
theFloats[ 4 ] = theZoom;
theFloats[ 2 ] = ( theRect.left * mScreenBase ) - ( theZoom * mBaseMatrixValues[ 2 ] ) + ( mViewWidth / 2 ); //Left
theFloats[ 5 ] = ( theRect.top * mScreenBase ) - ( theZoom * mBaseMatrixValues[ 5 ] ) + ( mViewHeight / 2 ); //Top
theFloats[ 8 ] = (float) 1.0;
theFloats = CheckBoundaries( theZoom, theFloats, theRect );
theMatrix.setValues( theFloats );
mPhotoView.setDisplayMatrix( theMatrix ); //Sets the mSuppMatrix in the PhotoViewAttacher
Matrix theImageViewMatrix = mPhotoView.getDisplayMatrix(); //Gets the new mDrawMatrix
mPhotoView.setImageMatrix( theImageViewMatrix ); //And applies it to the PhotoView (catches out of boundaries problems)
}
return true;
}
} );
}
private float[] CheckBoundaries(final float aZoom, float[] aFloats, final RectF aRect )
{
if( aZoom == 1.0 ) //If the zoom is all the way out
{
aFloats[ 2 ] = 0;
aFloats[ 5 ] = 0;
return aFloats;
}
theMaxLeftValue = ( ( mViewHeight * aZoom ) - mViewWidth + ( aZoom * mBaseMatrixValues[ 2 ] ) );
theMaxTopValue = ( ( mViewWidth * aZoom ) - mViewHeight + ( aZoom * mBaseMatrixValues[ 5 ] ) );
if( Math.abs( aFloats[ 2 ] ) > ( theMaxLeftValue ) )
{
aFloats[ 2 ] = -Math.abs( theMaxLeftValue ) + 10;
}
else if( Math.abs( aFloats[ 2 ] ) < ( aZoom * mBaseMatrixValues[ 2 ] ) )
{
aFloats[ 2 ] = -( aZoom * mBaseMatrixValues[ 2 ] );
}
if( Math.abs( aFloats[ 5 ] ) > ( theMaxTopValue ) )
{
aFloats[ 5 ] = -Math.abs( theMaxTopValue ) + 10;
}
else if( Math.abs( aFloats[ 5 ] ) < ( aZoom * mBaseMatrixValues[ 5 ] ) )
{
aFloats[ 5 ] = -( aZoom * mBaseMatrixValues[ 5 ] );
}
if( aFloats[ 2 ] > 0 )
aFloats[ 2 ] = -( mViewWidth / 2 );
else if( aFloats[ 5 ] > 0 )
aFloats[ 5 ] = -( mViewHeight / 2 );
return aFloats;
}
trying to use slide menu from function https://coronalabs.com/blog/2014/04/08/widgets-creating-a-sliding-panel/
I followed exactly the suggested code and I created a panel with 3 texts and one button. Then I added an event to the button to close the panel, but it does not work. Cannot understand why..:(. Here is the code:
local panel = widget.newPanel
{
location = "left",
--onComplete = panelTransDone,
width = display.contentWidth * 0.8,
height = display.contentHeight * 0.8,
speed = 500,
--inEasing = easing.outBack,
outEasing = easing.outCubic
}
panel.background = display.newRect( 100, -50, 900, 730 )
panel.background:setFillColor( 0.1, 0.1, 0.1, 0.9 )
panel:insert( panel.background )
panel.item1 = display.newText( "GAME DESCRIPTION", 0, 0, native.systemFontBold, 40 )
panel.item1:setFillColor( 1, 1, 0 )
panel.item1.x = -95
panel.item1.y = -350
panel:insert( panel.item1 )
panel.item2 = display.newText( "SET SOUNDS", 0, 0, native.systemFontBold, 40 )
panel.item2:setFillColor( 1, 1, 0 )
panel.item2.x = -170
panel.item2.y = -250
panel:insert( panel.item2 )
panel.item3 = display.newText( "CHECK SCORE", 0, 0, native.systemFontBold, 40 )
panel.item3:setFillColor( 1, 1, 0 )
panel.item3.x = -150
panel.item3.y = -150
panel:insert( panel.item3 )
panel.item4 = display.newText( "CLOSE", 0, 0, native.systemFontBold, 40 )
panel.item4:setFillColor( 1, 1, 0 )
panel.item4.x = -230
panel.item4.y = -50
panel:insert( panel.item4 )
local bottoneex = widget.newButton
{
--defaultFile = "play.png",
label="ESCI",
labelColor =
{
default = { 1, 1, 0, 255 },
},
font = native.systemFont,
fontSize = 40,
emboss = false,
textonly = true,
onEvent = provap
}
bottoneex.x = -250
bottoneex.y = 50
panel:insert( bottoneex )
function apripanel()
panel:show()
panel:toFront()
end
function provap()
panel:hide()
end
My target is to build a slide menu by adding to this panel several menu items. How can I achieve that? I tried putting a button ( textonly = true ) but I am not sure...what if I add displaytext (as I did)? How can I add listeners to texts?
Sorry for silly questions but I am quit new to this language! :)
Thanks a lot for your help! Ubaldo
Hiding the menu works for me, maybe you use an old version of newPanel.lua, this should work for you.
main.lua
widget = require("widget")
require("newPanel")
BG = display.newRect(160,240,300,460)
BG:setFillColor( 0.1, 0.1, 0.1, 1.0 )
local panel = widget.newPanel
{
location = "left",
onComplete = panelTransDone,
width = display.contentWidth*0.8,
height = display.contentHeight,
speed = 500,
inEasing = easing.outBack,
outEasing = easing.outCubic
}
panel.background = display.newRect( 0, 0, 320, 480 )
panel.background:setFillColor( 0.3, 0.3, 0.3, 0.9 )
panel:insert( panel.background )
panel.item1 = display.newText( "Item1", 0, 0, native.systemFontBold, 10 )
panel.item1:setFillColor( 1, 1, 0 )
panel:insert( panel.item1 )
local function ButtonEvent1(e)
if ( "ended" == e.phase ) then
print( "Button 1" )
panel:show()
panel:toFront()
end
end
local function ButtonEvent2(e)
if ( "ended" == e.phase ) then
print( "Button 1" )
panel:hide()
end
end
local B1 = widget.newButton({left = 100,top = 200,id = "button1",label = "Show",onEvent = ButtonEvent1})
local B2 = widget.newButton({left = 100,top = 300,id = "button2",label = "Hide",onEvent = ButtonEvent2})
newPanel.lua
function widget.newPanel( options )
local customOptions = options or {}
local opt = {}
opt.location = customOptions.location or "top"
local default_width, default_height
if ( opt.location == "top" or opt.location == "bottom" ) then
default_width = display.contentWidth
default_height = display.contentHeight * 0.33
else
default_width = display.contentWidth * 0.33
default_height = display.contentHeight
end
opt.width = customOptions.width or default_width
opt.height = customOptions.height or default_height
opt.speed = customOptions.speed or 500
opt.inEasing = customOptions.inEasing or easing.linear
opt.outEasing = customOptions.outEasing or easing.linear
if ( customOptions.onComplete and type(customOptions.onComplete) == "function" ) then
opt.listener = customOptions.onComplete
else
opt.listener = nil
end
local container = display.newContainer( opt.width, opt.height )
if ( opt.location == "left" ) then
container.anchorX = 1.0
container.x = display.screenOriginX
container.anchorY = 0.5
container.y = display.contentCenterY
elseif ( opt.location == "right" ) then
container.anchorX = 0.0
container.x = display.actualContentWidth
container.anchorY = 0.5
container.y = display.contentCenterY
elseif ( opt.location == "top" ) then
container.anchorX = 0.5
container.x = display.contentCenterX
container.anchorY = 1.0
container.y = display.screenOriginY
else
container.anchorX = 0.5
container.x = display.contentCenterX
container.anchorY = 0.0
container.y = display.actualContentHeight
end
function container:show()
local options = {
time = opt.speed,
transition = opt.inEasing
}
if ( opt.listener ) then
options.onComplete = opt.listener
self.completeState = "shown"
end
if ( opt.location == "top" ) then
options.y = display.screenOriginY + opt.height
elseif ( opt.location == "bottom" ) then
options.y = display.actualContentHeight - opt.height
elseif ( opt.location == "left" ) then
options.x = display.screenOriginX + opt.width
else
options.x = display.actualContentWidth - opt.width
end
transition.to( self, options )
end
function container:hide()
local options = {
time = opt.speed,
transition = opt.outEasing
}
if ( opt.listener ) then
options.onComplete = opt.listener
self.completeState = "hidden"
end
if ( opt.location == "top" ) then
options.y = display.screenOriginY
elseif ( opt.location == "bottom" ) then
options.y = display.actualContentHeight
elseif ( opt.location == "left" ) then
options.x = display.screenOriginX
else
options.x = display.actualContentWidth
end
transition.to( self, options )
end
return container
end
I have managed to build a simple jQuery flash card game following an online tutorial, resulting in this code:
var eng2fr = {
from: null,
to: null,
suggester: {
i: 0,
words: [
[ "beer", "binouze" ],
[ "another beer", "une autre bière" ],
[ "crazy", "fou" ],
[ "What the heck?!", "c'est quoi ce délire" ],
[ "whatever", "n'importe quoi"]
],
next: function(){
return this.words[ ( this.i++ ) % this.words.length ];
}
},
init: function(el) {
this.bindSwipe( $( "#display" ) );
this.from = $( "#from" );
this.to = $( "#to" );
Events.listen( "card_next", $.proxy( this.next, this ) );
Events.listen( "card_flip", $.proxy( this.flip, this ) );
// Begin!
this.next();
},
next: function() {
var to = this.to,
from = this.from,
next = this.suggester.next(),
_this = this;
to.text( next[ 0 ] );
to.addClass( "push in current" );
from.addClass( "push out" ).one( "webkitAnimationEnd", function() {
from.text( next[ 1 ] );
from.removeClass( "current push out" );
to.removeClass( "push in" );
_this.from = to;
_this.to = from;
});
},
flip: function() {
var to = this.to,
from = this.from,
_this = this;
to.addClass( "flip in current" );
from.addClass( "flip out" ).one( "webkitAnimationEnd", function() {
from.removeClass( "current flip out" );
to.removeClass( "flip in" );
_this.from = to;
_this.to = from;
});
},
bindSwipe: function( el ) {
this.xStart = null;
this.downEvent = 'ontouchstart' in document.documentElement && navigator.appVersion.indexOf( 'iPhone OS ' ) > -1 ? 'touchstart' : 'mousedown';
this.upEvent = 'ontouchend' in document.documentElement && navigator.appVersion.indexOf( 'iPhone OS ' ) > -1 ? 'touchend' : 'mouseup';
var _this = this;
el.bind({
"touchstart mousedown": function( e ) {
if( e.type !== _this.downEvent ) return;
e.preventDefault();
_this.xStart = e.pageX && e.pageX > 0 ? e.pageX : e.originalEvent.changedTouches[ 0 ].pageX;
},
"touchend mouseup": function( e ) {
if( e.type !== _this.upEvent ) return;
var newX = e.pageX && e.pageX > 0 ? e.pageX : e.originalEvent.changedTouches[ 0 ].pageX;
var diff = newX - _this.xStart;
if( Math.abs( diff ) > 20) {
if( diff > 0 ){
Events.trigger( "card_previous", {} );
} else {
Events.trigger( "card_next", {} );
}
} else {
Events.trigger( "card_flip", {} );
}
},
"touchmove": function( e ) {
e.preventDefault();
}
});
}
};
As you can probably see, this code relies on mouse events for flipping and browsing through cards. I'm looking to implement jQuery mobile swipe/tap functions in place of these and I was wondering if someone could help me with that or at least point me in the right direction.
Also, I'm wondering if there is a simple way to detect a shake event and use this to select a random "card" / word pair?
I'm having a problem when I try to restart my game. I pause the physics, then when the user clicks the button, the physics are supposed to restart. When I put in physics.start(), though the game crashes. So, I was wondering if it's possible to pause one physical object and then change it's position on the screen. I'm kind of a newb so any answer will be helpful.
local physics = require( "physics")
physics.start( )
local crate1 = display.newRect( display.contentWidth/2,display.contentHeight/2, 40,40)
physics.addBody( crate1, { density=4.0, friction=0.3, bounce=.4} )
crate1.bodyType = "dynamic"
crate1.isBodyActive = true
crate1:setFillColor( 1,0,.3)
sky = display.newRect( display.contentWidth/2, .5, display.contentWidth, 0.000000000000000000001)
physics.addBody( sky, {density=4.0, friction=0.3, bounce=1.5} )
sky.bodyType = "static"
ground = display.newRect( display.contentWidth/2, display.contentHeight, display.contentWidth, .00000000001 )
physics.addBody( ground, {density=4.0, friction=0.3, bounce=1.5 } )
ground.bodyType = "static"
rightWall = display.newRect( display.contentWidth, display.contentHeight/2, 1, display.contentHeight )
physics.addBody( rightWall, {density=4.0, friction=0.3, bounce=1.5} )
rightWall.bodyType = "static"
leftWall = display.newRect(1, display.contentHeight/2, .0000000001, display.contentHeight )
physics.addBody( leftWall, {density=4.0, friction=0.3, bounce=1.5} )
leftWall.bodyType = "static"
physics.setGravity( 0, 3 )
local function handleCollisionOnDelay( event )
local obj = event.source.object
obj.isBodyActive = false
end
local function onLocalCollision( self, event )
if ( event.phase == "began" ) then
local dr = timer.performWithDelay( 10, handleCollisionOnDelay )
dr.object = self
crate1.x = display.contentWidth/2
crate1.y = display.contentHeight/2
end
end
crate1.collision = onLocalCollision
crate1:addEventListener( "collision", crate1 )
use isBodyActive property
http://docs.coronalabs.com/api/type/Body/isBodyActive.html
good luck