Using an arraylist for multiple if conditions - android

I changed my mind about using swipemotions: As it is rather complicated to use swipemotions, I decided to just use simple buttons with 'bigger' and 'smaller'
I'm currently working on a school project in Android Studio and so far I've written a code which generates a random equation.
Here is the code which gereates the random equation:
String[] operationSet = new String[]{"+", "-", "/", "*"};
String stringResultOfEquation;
String equation;
double doubleAnswer1;
public void start1() {
Random random = new Random();
int numOfOperations = random.nextInt(2) + 1;
List<String> operations = new ArrayList<>();
for (int i = 0; i < numOfOperations; i++) {
String operation = operationSet[random.nextInt(4)];
operations.add(operation);
}
int numOfNumbers = numOfOperations + 1;
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < numOfNumbers; i++) {
int number = random.nextInt(10)+1;
numbers.add(number);
}
String equation = "";
for (int i = 0; i < numOfOperations; i++) {
equation += numbers.get(i);
equation += operations.get(i);
}
equation += numbers.get(numbers.size() -1);
TextView TextEquation = (TextView)findViewById(R.id.textView3);
TextEquation.setText(equation);
String stringResultOfEquation = String.valueOf(equation);
double doubleAnswer1 = eval(stringResultOfEquation);
String stringAnswer = Double.toString(doubleAnswer1);
TextView textAnswer = (TextView)findViewById(R.id.textView4);
textAnswer.setText(stringAnswer);
}
Now the app displays two equations on the screen and the user then has to dicide wether the second equation has a bigger or smaller result than the first one. If the second equation is bigger, the user has to do a swipemotion UP and if the second equation is smaller, the user has to do a swipemotion DOWN.
However I don't know how to write the code for this. I tried this:
if((doubleAnswer1 > doubleAnswer2) && (MotionEvent.ACTION_DOWN = true)){
//create new equation
}
but that didn't work. It told me that "Operator && can't be applied to boolean, int"
Now I'm curious if I could use an arraylist like this:
if(doubleAnswer1 > doubleAnswer2){
// put "smaller" to arraylist
} else {
// put "bigger" to arraylist
}
if(MotionEvent.ACTION_DOWN = true){
// put "smaller" to arraylist
}
if(MotionEvent.ACTION_UP = true){
// put "bigger" to arraylist
}
Then the code would check the arraylist if the elemnts of the arraylist are the same. If so, the next equation will be generated. If the elemnts of the arraylist are different, the process will be stopped.
I really don't know if that would work, so could someone maybe tell me if?
Or is there an other way to solve my problem?
If anything is unclear in my question, feel free to ask and I will try to clarify the problem :)
Thank you already in advance for your help!

When you write such statement editor will tell you (Android studio hope so) that you can't compare int with boolean. as it is tendency that zero means false and 1 means true but in java you can't do like that.
you can try like this
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
return false;
}
return false;
}
Hope will help in understanding...

"=" is an assignment,
for comparing a value use "==".
regarding recognizing gesture, check out https://developer.android.com/training/gestures/detector.html#detect and https://developer.android.com/reference/android/view/GestureDetector.html
You need something like this:
#Override
public void onCreate(Bundle savedInstanceState) {
...
mDetector = new GestureDetectorCompat(this,this);
...
}
#Override
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
Log.d(TAG, "fling! - direction is " + (velocityY > 0 ? "down" : "up"));
return true;
}

Related

How to render RTL text correct on older Android versions

I've used Google Translate to translate the following string "I think CompanyXYZ is a great company in 2014 and beyond" to Hebrew and this resulted in
When I display this text in a TextView on a Galaxy S3 (Android 4.3), I get
which seems to be correct.
When I run the same program on a Galaxy Tab 7 (running Android 2.2), I get
which is obviously not correct.
Can I use android.support.v4.text.BidiFormatter and/or java.text.Bidi to render this correct?
When running the following code
Bidi bidi = new Bidi(text, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
for (int i = 0; i < bidi.getRunCount(); i++)
{
int start = bidi.getRunStart(i);
int level = bidi.getRunLevel(i);
int limit = bidi.getRunLimit(i);
Log.d("RTL", "bidi.run["+i+"] = "+start+";"+level+";"+limit+";"+ text.substring(start, limit));
}
I do get the following 5 runs
bidi.run[0] = 0;1;9;אני חושב
bidi.run[1] = 9;2;19;CompanyXYZ
bidi.run[2] = 19;1;36; היא חברה גדולה ב
bidi.run[3] = 36;2;40;2014
bidi.run[4] = 40;1;46; ומעבר
Hence all the information seems to be available to render this string correct but I don't know how to proceed. Can I use BidiFormatter? Or should I override TextView.draw()?
Ok, I realize it's been a while...
I made a function for my app which gets bidirectional strings, depending on the main direction which I thought would be helpful.
public static String getBidiString(String input, int direction) {
boolean rtlContext;
int defaultBidiDirection;
if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT) {
rtlContext = false;
defaultBidiDirection = Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
} else /* if (lang == Util.Lang.HE) */{
rtlContext = true;
defaultBidiDirection = Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
}
Bidi bidi = new Bidi(input,defaultBidiDirection);
if (!bidi.isMixed()) return input;
BidiFormatter bidiFormatter = BidiFormatter.getInstance(rtlContext);
StringBuilder bidiTestBuilder = new StringBuilder();
for (int i = 0; i < bidi.getRunCount(); i++)
{
int start = bidi.getRunStart(i);
int level = bidi.getRunLevel(i);
int limit = bidi.getRunLimit(i);
String run = input.substring(start, limit);
if (level != direction) {
run = bidiFormatter.unicodeWrap(run,!rtlContext) + " ";
}
bidiTestBuilder.append(run);
}
return bidiTestBuilder.toString();
}
the direction parameter should be either Bidi.DIRECTION_LEFT_TO_RIGHT or Bidi.DIRECTION_RIGHT_TO_LEFT depending on the default direction of the text.
I certainly am not claiming that I implemented this completely correctly, but this code works for my use cases.
Rendering on your 2.2 device is not incorrect. The difference is that the paragraph direction is LTR. It is very common to set paragraph orientation "by context", which means - according to the first bid I run. But it is legitimate to set the direction otherwise. For example, Windows textbox allows the end user switch this direction by pressing left ctrlshift or right ctrlshift (left or right shift, does not matter). Usually, alignment follows this direction.
Official support for RTL layout direction was introduced in 4.2. But even before, since 2011 (it seems to be 4.0.1), there has been a #hide method View.setLayoutDirection() credits to Du Shunpeng, who published his answer a year ago.
Unfortunately, 2.2 is even older, and this non-public API was not available. Consider using WebView, it does support dir=rtl for div and text input.
Note that even back then, the ME versions of Android, including the Tab 7 device, were often customized by the manufacturer or distributor to provide some level of BiDi support, so it's important to test on the device that will be used by your audience.
I think below code can help you
public static Spannable getRtlBidiString(String input)
{
return getBidiString(Spannable.Factory.getInstance().newSpannable(input), Bidi.DIRECTION_RIGHT_TO_LEFT);
}
public static Spannable getForceRtlBidiString(String input)
{
return getForceBidiString(Spannable.Factory.getInstance().newSpannable(input), Bidi.DIRECTION_RIGHT_TO_LEFT);
}
public static Spannable getRtlBidiString(Spannable input)
{
return getBidiString(input, Bidi.DIRECTION_RIGHT_TO_LEFT);
}
public static Spannable getLtrBidiString(Spannable input)
{
return getBidiString(input, Bidi.DIRECTION_LEFT_TO_RIGHT);
}
public static Spannable getLtrBidiString(String input)
{
return getBidiString(Spannable.Factory.getInstance().newSpannable(input), Bidi.DIRECTION_LEFT_TO_RIGHT);
}
public static Spannable getBidiString(Spannable input, int direction)
{
boolean isRtl;
int baseDirection;
TextDirectionHeuristicCompat heu;
if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT)
{
isRtl = false;
baseDirection = Bidi.DIRECTION_LEFT_TO_RIGHT;
heu = TextDirectionHeuristicsCompat.FIRSTSTRONG_LTR;
}
else /* if (lang == Util.Lang.HE) */
{
isRtl = true;
baseDirection = Bidi.DIRECTION_RIGHT_TO_LEFT;
heu = TextDirectionHeuristicsCompat.FIRSTSTRONG_RTL;
}
Bidi bidi = new Bidi(input.toString(), baseDirection);
if (!bidi.isMixed())
return input;
BidiFormatter bidiFormatter = BidiFormatter.getInstance(isRtl);
SpannableStringBuilder bidiBuilder = new SpannableStringBuilder();
for (int i = 0; i < bidi.getRunCount(); i++)
{
int start = bidi.getRunStart(i);
int level = bidi.getRunLevel(i);
int limit = bidi.getRunLimit(i);
CharSequence run = input.subSequence(start, limit);
if (level != baseDirection)
{
run = bidiFormatter.unicodeWrap(run, heu, !isRtl).toString();
}
bidiBuilder.append(run);
}
return bidiBuilder;
}
public static Spannable getForceBidiString(Spannable input, int direction)
{
boolean isRtl;
int baseDirection;
TextDirectionHeuristicCompat heu;
if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT)
{
isRtl = false;
baseDirection = Bidi.DIRECTION_LEFT_TO_RIGHT;
heu = TextDirectionHeuristicsCompat.ANYRTL_LTR;
}
else /* if (lang == Util.Lang.HE) */
{
isRtl = true;
baseDirection = Bidi.DIRECTION_RIGHT_TO_LEFT;
heu = TextDirectionHeuristicsCompat.ANYRTL_LTR;
}
Bidi bidi = new Bidi(input.toString(), baseDirection);
if (!bidi.isMixed())
return input;
BidiFormatter bidiFormatter = BidiFormatter.getInstance(isRtl);
SpannableStringBuilder bidiBuilder = new SpannableStringBuilder();
for (int i = 0; i < bidi.getRunCount(); i++)
{
int start = bidi.getRunStart(i);
int level = bidi.getRunLevel(i);
int limit = bidi.getRunLimit(i);
CharSequence run = input.subSequence(start, limit);
if (level != baseDirection)
{
run = bidiFormatter.unicodeWrap(run, heu, !isRtl).toString();
}
bidiBuilder.append(run);
}
return bidiBuilder;
}

Java, what is best way to compare two lists?

I have two lists of Default and Chrome browsers history.
I want to merge these two lists into one list.
I need to update item if I find it duplicate (is common between two lists).
So, my "BrowserRecord" class is like this:
public class BrowserRecord {
private long id;
private int bookmark;
private long created;
private long date;
private String title;
private String url;
private long visits;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BrowserRecord record = (BrowserRecord) o;
return url.equals(record.url);
}
#Override
public int hashCode() {
return url.hashCode();
}
// other getter setter methods
...
}
and finally, I have a method that gets browsers histories and does merging:
public List<BrowserRecord> getHistory() {
List<BrowserRecord> browserList = new ArrayList<BrowserRecord>();
// get history of default and chrome browsers
List<BrowserRecord> defaultList = getDefaultBrowserHistory();
List<BrowserRecord> chromeList = getChromeBrowserHistory();
Log.e(TAG, "=> size of Default browser:" + defaultList.size());
Log.e(TAG, "=> size of Chrome browser:" + chromeList.size());
// compare list A with B, update A item if equal item found in B and push it to tempList
for(int i=0; i<chromeList.size(); i++) {
BrowserRecord chromeBrowser = chromeList.get(i);
for(int j=0; j<defaultList.size(); j++) {
BrowserRecord defaultBrowser = defaultList.get(j);
if(chromeBrowser.equals(defaultBrowser)) {
if(chromeBrowser.getBookmark() != defaultBrowser.getBookmark())
chromeBrowser.setBookmark(1);
chromeBrowser.setVisits(chromeBrowser.getVisits() + defaultBrowser.getVisits());
}
}
browserList.add(chromeBrowser);
}
// compare list B with A, jump if equal item found in A, push to tempList if item not found
for(int i=0; i<defaultList.size(); i++) {
BrowserRecord defaultBrowser = defaultList.get(i);
boolean found = false;
for(int j=0; j<chromeList.size(); j++) {
BrowserRecord chromeBrowser = chromeList.get(j);
if(defaultBrowser.equals(chromeBrowser)) {
found = true;
break;
}
}
if(!found)
browserList.add(defaultBrowser);
}
Log.e(TAG, "=> size of final browser:" + browserList.size());
return browserList;
}
I have tested this method and is working fine. Since my history records on mobile device after 3 years didn't exceed more than 200 records on one list and 150 for others, I assume something similar is happening for other users. But I'm sure is not optimum way.
What do you recommend?
any suggestion would be appreciated. Thanks.
Not sure I understand correctly, but it seems like what you're trying to do is, given both lists, create a final list which will contain all of the elements from both lists, removing any duplicates.
If this is the case, then take a look at Java's TreeSet class. If you iterate over all of the elements from both your lists and insert them into a TreeSet, you will basically get the result you're looking for. You can then use an Iterator to create an ArrayList containing all of the non-duplicate items from both your lists. As a side-effect of using a TreeSet, they will ordered (you can also use either a HashSet if you don't care about the order or a LinkedHashSet if you want to preserve the order of insertion).

Indexing Android

My problem is I have around 1000+ records in an Android App
string field1;
string field2;
string field3;
string field4;
//...
I want to search in this set of records and get the best results on two fields (field1 and field2).
Currently I read each record and compare() (string compare) with the text i want to search so that takes a long time.
What is the best method to perform search?
Store each records in SQLite DB and do "select query where like"
Hash-Mapped
? any other suggestions?
Or may be create an Index of the records and do search.
If you want to search for not exact matches, I would try to make an ArrayList of MyAppRecord where
public class MyAppRecord {
private String record;
private int deviance;
}
and get for each record the deviance of the String you want to find with:
public static int getLevenshteinDistance (String s, String t) {
if (s == null || t == null) {
throw new IllegalArgumentException("Strings must not be null");
}
int n = s.length(); // length of s
int m = t.length(); // length of t
if (n == 0) {
return m;
} else if (m == 0) {
return n;
}
int p[] = new int[n+1]; //'previous' cost array, horizontally
int d[] = new int[n+1]; // cost array, horizontally
int _d[]; //placeholder to assist in swapping p and d
// indexes into strings s and t
int i; // iterates through s
int j; // iterates through t
char t_j; // jth character of t
int cost; // cost
for (i = 0; i<=n; i++) {
p[i] = i;
}
for (j = 1; j<=m; j++) {
t_j = t.charAt(j-1);
d[0] = j;
for (i=1; i<=n; i++) {
cost = s.charAt(i-1)==t_j ? 0 : 1;
// minimum of cell to the left+1, to the top+1, diagonally left and up +cost
d[i] = Math.min(Math.min(d[i-1]+1, p[i]+1), p[i-1]+cost);
}
// copy current distance counts to 'previous row' distance counts
_d = p;
p = d;
d = _d;
}
// our last action in the above loop was to switch d and p, so p now
// actually has the most recent cost counts
return p[n];
}
}
save it to your MyAppRecord-object and finally sort your ArrayList by the deviance of its MyAppRecord-objects.
Note that this could take some time, depending on your set of records. And NOTE that there is no way of telling wether dogA or dogB is on a certain position in your list by searching for dog.
Read up on the Levensthein distance to get a feeling on how it works. You may get the idea of sorting out strings that are possibly to long/short to get a distance that is okay for a threshold you may have.
It is also possible to copy "good enough" results to a different ArrayList.

Android update array of bitmaps / Queue

I need some advice how to implement this situation in my application.
I have array of bitmpaps, which I'm using to store different states of my Canvas, so I can use them in the future. Here is the code which I'm using :
private Bitmap[] temp;
// on user click happens this ->
if(index<5){
temp[index] = Bitmap.createBitmap(mBitmap);
index++;
}
So basically I want to save only the last 5 bitmaps depending on user's actions. The things which I want to learn is how can I update my array so I can always have the last 5 bitmaps.
Here is what I mean :
Bitmaps [1,2,3,4,5] -> after user clicks I want to delete the first bitmap, re-order the array and save the new one as the last..so my array should look like this : Bitmaps[2,3,4,5,6];
Any suggestions / advices which is the best way to do that?
Thanks in advance!
I just wrote this...
Use this code to initialise:
Cacher cach = new Cacher(5);
//when you want to add a bitmap
cach.add(yourBitmap);
//get the i'th bitmap using
cach.get(yourIndex);
Remember you can re implement the function get to return the ith "old" Bitmap
public class Cacher {
public Cacher(int max) {
this.max = max;
temp = new Bitmap[max];
time = new long[max];
for(int i=0;i<max;i++)
time[i] = -1;
}
private Bitmap[] temp;
private long[] time;
private int max = 5;
public void add(Bitmap mBitmap) {
int index = getIndexForNew();
temp[index] = Bitmap.createBitmap(mBitmap);
}
public Bitmap get(int i) {
if(time[i] == -1)
return null;
else
return temp[i];
}
private int getIndexForNew() {
int minimum = 0;
long value = time[minimum];
for(int i=0;i<max;i++) {
if(time[i]==-1)
return i;
else {
if(time[i]<value) {
minimum = i;
value = time[minimum];
}
}
return minimum;
}
}

Points changing rapidly

I like to make a game, but I get trouble with collecting points.
The purpose is to increase/decrease character point (charhop +1 or -1) whenever object 'face' is collided with injekBox, but the point just increase or decrease once then it return to the previous value.
The log also still print the value even if the object stop
I want to make the point change once if the 'face' collided with certain box, and will change again after collided with another box
char1.setHops(0);
public void onUpdate(final float pSecondsElapsed) {
if (char1.isJump()){
int rockPoint = char1.getPoints();
int maxBox = listBox.size();
int charHop = char1.getHops();
for (int j = 0; j < maxBox ; j++){
if (j == rockPoint){
j++;
}
Box injekBox = listBox.get(j);
if(injekBox.getRectangle().collidesWith(face)){
if(char1.isTurn()){
charHop++;
if (charHop == (maxBox - 1)){
char1.setTurn(false);
}
} else {
charHop--;
}
Log.i(this.toString(),"charHop: "+charHop);
injekBox.getRectangle().setColor(1, 0, 0);
} else {
injekBox.getRectangle().setColor(1, 1, 1);
}
}
}
}
Sorry for bad writing...
Thank you for attention :)
The scope of charHop is only within onUpdate. Once you leave that method, the contents of that variable is gone. You need the counterpart to char1.getHops()--something like char1.setHops(charHop);.

Categories

Resources