This is the simplified version of my question.
There are
movieclip1
movieClip2
movieClipadd
TextA
TextB
Text C
Text answer
Touching movieclip1 should change TextA to 1 (the content should be 1)
Touching movieclip2 should change TextC to 2 (the content should be 2)
Touching movieclipadd should change TextB to + (the content should be +)
Then automatical Textanswer should give the answer. that is 3(1+2=3)
This is for mobile and I know to use ontouchbegin and ontouchend.
There's a couple of ways to accomplish what you want to do, one way would be to have a method for each operation type that you plan to have your calculator support, then you can just have a switch statement that calls the appropriate method, something like this (I got lazy and just did the operation inline, if it were more complicated would probably want methods):
switch(textB.text)
{
case '+': textAnswer.text = parseInt(textA.text)+parseInt(textC.text);
break;
case '-': textAnswer.text = parseInt(textA.text)-parseInt(textC.text);
break;
//etc.
default: throw new Error('unhandled operator');
}
assuming that you are going to use your knowledge of the touch handlers to populate the text boxes.
While I sort of agree with arunkumar due to the lack of code provided it's a simple enough problem with enough easy solutions to provide one. But note that on SO it is standard that you provide your current work and as much background information as is relevant.
Related
I'm working on a tile memory game.
A user can press any one of the tiles on a 9x9 board.
However, I want to limit the user to being only to press one at a time.
I've tried researching using a TableLayout, setting beforeAscendants=true, and having that try to manage where a user's click goes, but that proves tedious and saving all those coordinates seems inefficient to the possibility of an easier solution existing.
Right now, I call .setOnClickListener on each of those tiles and setting them to the same onClickListener, but there's no way to limit how many tiles can be pressed at once. I've tried A) setting a synchronized() section around the code inside the anonymous onClickListener code, B) having a boolean to set to true if one tile is already in the onClickListener code but it's simply ignored and C) banging my head against the wall, didn't help
Thanks!
This is the most straightforward and simplest way I can come out with. You should optimize the logic too, it's pretty lengthy here.
onClick(View v) {
switch (v.getId()) {
case R.id.tile1:
// Tile 1 is clicked
// Disable other tiles (try setClickable(false))
break;
...
default:
break;
}
}
Alright... No one laugh... I am working on an app in MIT/Google Appinventor. Here's a rundown:
Scans a barcode then runs the pictured function.
If the item is in the list then
Find that items position index in the inventory list.
Use that items index, to increment the value in the quantity list by 1.
If the item is not in the list then
Add that item to the inventory, and add a "1" to the quantity.
I can't see why it won't work so I was just checking to see if there are any obvious flaws in my logic. If the logic looks solid, then I should be able to figure out the Appinventor problem to make it work.
Here's your function translated (accurately?) into pseudo-code to help with my own understanding (and hopefully others'):
function addItem:
if inventoryList.contains(scannerResult):
inventoryPosition = inventoryList.positionOf(scannerResult)
quantityPosition = quantityList.positionOf(scannerResult)
quantityItem = quantityList.selectListItemAt(quantityPosition)
quantityList.insert(quantityItem at inventoryPosition)
else
inventoryList.add(scannerResult)
quantityList.add(1)
The problem appears to be in the logic when the scanner result is already in the list. I don't know the relevant app-inventor functions, but I think that you want something more like:
if inventoryList.contains(scannerResult):
inventoryPosition = inventoryList.positionOf(scannerResult)
quantity = quantityList.selectListItemAt(inventoryPosition)
quantityList.setListItemAt(quantityPosition to quantity + 1)
That last line is the bit I don't know how to translate into app-inventor language, but hopefully it's enough to point you in the right direction.
#blahdiblah made a good analysis of the problem.
The solution with App Inventor looks like this: instead of the insert list item block you have to use the replace list item block
I have a Service that sends an Intent to my Activity every 0.1 seconds. I use it to update a custom implementation of a Chronometer. Here everything goes right. The problem comes when I want to update 14 TextView I have in a TableView inside a Fragment in my Activity. Here the app is very slow.
The method in my Activity where it receives the Intent from the Service:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long milis = intent.getLongExtra("milis",0);
if( mFragment != null)
mFragment.Update(milis);
}
};
The code inside the Fragment where I update the TextViews:
public void actualizarTiempoJuego(long milis){
// Se recuperan los tiempos acumulados y se aumenta la cantidad pasada como parĂ¡metro
for(int i=0;i<7;++i) {
long mCurrentMilis1 = mVectorMilis1.get(i);
long mCurrentMilis2 = mVectorMilis2.get(i);
TextView1 t1 = mListaTitularLayoutLocal.get(i);
TextView1 t2 = mListaTitularLayoutVisitante.get(i);
t1.setText(String.value(milis + mCurrentMilis1));
t2.setText(String.value(milis + mCurrentMilis2));
}
}
Am I doing anything wrong, or is it just that I'm trying to do something very complex in terms of efficiency?
#Sherif brings up a good point about hidden alpha values that bog down your application a lot.
Depending on your platform you may also want to check
<application android:hardwareAccelerated="true"... />
Another thing you can look into that may help performance is not firing off all those Intents. Once you start firing intents you are getting the system involved and depending on how they are getting resolved it may take some extra time.
For this issue I like to use Handlers. They are more light weight than intent.
You may also want to look at AsyncTask. This is basically like a thread, but also gives hooks that run on the UI Thread so you can perform both perform a background operation and update the UI without have to post runnables.
EDIT: Lastly, you can always run your layouts through the layoutopt tool. I was personally told by Romain Guy himself that if your drawing too slow, than you need to draw less. Just check out a screenshot (from a less than ideal view tree, but well within the max) from the profiling tool. You can see how much of the resources view drawing takes up. It's very important to keep this as lean as possible if you want your app to be responsive.
EDIT: It is no longer called layoutopt, it's called lint. Check your ~/android-sdk/tools/
I have once faced a situation where a fragment was really slow.
I am just predicting that your fragment has some kind of alpha and it is drawn on a 'heavy' activity.
The conclusion is that each time you are setting the text of a textview your whole view hierarchy is being invalidated.
It seems that fragments have this flaw. Anyway, use some layout instead of the fragment and check if it remains 'slow'.
ADDITION: A wrap_content textview will cause much more delay after a setText than a fill_parent textview.
You're likely running into slowdowns due to layout management with TableLayout and TextView. Every time you update text in one of those, a large amount of view measuring has to take place in order to put the characters in the right place on the screen. You should really just profile the app yourself using Traceview to find out. More information at: http://developer.android.com/tools/debugging/debugging-tracing.html
I've had the exact same issue you're seeing with the same type of layout (Fragment > TableLayout > Multiple TextViews). One way to test if your TableLayout/TextView setup is to blame is simply replace all that with a single TextView. That will probably run pretty well. Then put your 14 views into a FrameLayout or RelativeLayout. Even if they all overlap, you should still get decent performance, because it's the complexity of the TableLayout view measurements that's really causing slowdown.
As someone said you can use HardwareAccelerated but this is not a great solution, you will waste ram and cpu if you can't solve it in a different way. A solution probably more safety is to reduce the number of TextView. Try to reduce 14 to 7 and it will go twice faster. Usually is hard to do it but if you put the objects in a strategy position a pair of TextView one above other can be together if you make a TextView with two lines. And don't forget that findViewById is so expensive, if you will use a view object often find it one time and hold its reference.
Benchmarks are always useful for determining where slowness actually comes from, but I feel pretty confident suggesting that sending an Intent is probably much slower than updating 14 TextViews. Sending 10 Intents per second is a sign that you're Doing It Wrong (TM). This is just isn't what they're for.
Am I doing anything wrong, or is it just that I'm trying to do something very complex in terms of efficiency?
Updating 14 TextViews per second isn't inherently complex; you should be able to easily achieve this with a more appropriate application design. ASyncTask or Handler come to mind as possible tools, but it's hard to know what's best without knowing more about exactly what you're trying to do.
You can try to declare vars outside the loop :
public void actualizarTiempoJuego(long milis){
// Se recuperan los tiempos acumulados y se
// aumenta la cantidad pasada como parĂ¡metro
long mCurrentMilis1;
long mCurrentMilis2;
TextView1 t1;
TextView1 t2;
for(int i=0;i<7;++i) {
mCurrentMilis1 = mVectorMilis1.get(i);
mCurrentMilis2 = mVectorMilis2.get(i);
t1 = mListaTitularLayoutLocal.get(i);
t2 = mListaTitularLayoutVisitante.get(i);
t1.setText(String.value(milis + mCurrentMilis1));
t2.setText(String.value(milis + mCurrentMilis2));
}
}
And to setText() with mixed type, you can try setText("" + milis + mCurrentMilis2);
I cant found the topic, perhaps someone can teach me some about android effectivity when the topis is about onclicklistener for buttons.
Lets say I got 10 buttons on a page (just an example now)
What's the best thing to do?
A switch that switch id for the buttons?
A onClickListener for each button?
What method is the faster one, and why?
Is there any different at all?
Best practice is to go with 1st option: A switch that switch id for the butttons.
As per my experience, i would suggest you to assign android:onClick attribute with same value, say for example: android:onClick="btnClicker"
And now you have to implement the same method inside the activity class as:
public void btnClicker(View v)
{
switch(v.getId())
{
case R.id.btn1:
break;
case R.id.btn2:
break;
case R.id.btn3:
break;
}
}
About 2nd option:
I don't prefer it because it increase number of code lines because just think you are having 10 buttons and you assign separate click listener for each buttons. And now compare it with the above 1st option, you will realize it.
So i would suggest you to go with 1st option i have suggested with example above, main reason is it decrease number of code lines and better readability of code.
Why there is better readability in 1st option i have suggested above?
Because you know you just have to check this particular function only for the code for every buttons, because everything is here inside a function.
I would be surprised if there is any significant difference. I would go with #2 because I think it leads to clearer code.
I think answer 1 is effectivity.
because create object will slow down the app.
and the RAM limit in mobile phone should be considered.
I am developing the calculator for android.
I have implemented all the functionality, Now just getting stop at the decimal value.
I dont know how to implement that functionality on the click of custom "." button.
I want decimal value up to two fraction point.
can anybudy help me to develop such code?
I need it. . . I know it seem very easy but right now i got stuck in that matter.
Pleae help me in this
Thanks in advance.
As it is, this is a very broad question. I recommend you to check this http://www.codeproject.com/KB/android/androidcalculator.aspx
Generally speaking, you need to:
1) Implement UI
2) Implement click handlers for the buttons
3) Implement evaluation function
If you get stuck at something particular ask it here and post your code.
EDIT:
There you can see how it is implemented, you can use similar logic:
case DECIMAL_SEP: // Handle decimal seperator
if (hasFinalResult || resetInput) { // if previous result is calculated or the input is reset, insert 0 before
userInputText.setText("0.");
hasFinalResult = false;
resetInput = false;
} else if (currentInput.contains(".")) // don't let 2nd '.'
return;
else
userInputText.append("."); // append '.'
break;