Hi mobile devs, I am noob to android studio and java, but have some c and c++ basic knowledge so not noob to programming in general.
However I am also noob to all aspects of form design.

I did not write title of Question singular because I'm pretty sure I'll have a few as I progress, so It's possible this thread might serve other android noobs.

I downloaded Android studio 4.6 but during installation downloaded patch/upgrade to 5.7.

My first question, which I'm not to certain how to term is...

In the activity_main.xml tab where I can see physical layout and design app front there appears to be a grid which things fit or snap to.

I have provided an image of when I try to move a button, there are 9 segments to the grid, and my button can only go in one of them....

http://s14.postimg.org/caivdze2p/Android_Q1.jpg

I'm going to need more buttons than would fit, so how can I get rid of that grid so I can freehand (for want of a better word) my app front to wherever and whatever size I choose?

Apologize for long post but wanted to be verbose in case I'm not getting terminology correct.

Thanks for taking time to read and any help or tips is greatly appreciated.

Recommended Answers

All 18 Replies

GridLayout takes a collection of items. So you need to design layout of a singular item. Then you create adapter, tell it to use your item layout, provide and provide collection of data you want to populate your grid with. You can read on it here http://developer.android.com/guide/topics/ui/layout/gridview.html

BTW, if I can recommend it is better to learn hands about each view and code by hand at beginning and use UI builder later when you know what the component is expecting and what it will do for you.

I believe the issue above is simply due to screen sizes being different.

I have another question, the emulator seems to be painfully slow to load, wondering if there's anything I can do to speed the loading time up.

When I set it up I ticked box to use host GPU but it's still awfully slow.

Yes difference been them is down to screen sizes, you would need to provide layouts for mdpi, hdpi etc. which do provide different sizes of buttons, fonts, spacing and other

  1. It is good to have at least 8GB RAM so you can assigned more memory to emulator then 128MB that it will get by default
  2. Give emulator more power, I use following on emulator for Nexus 4 Target: 4.1.2, CPU/ABI: Intel Atom (x86), Memory options RAM: 2048, VM Heap: 1024
  3. Unfortunately Android SDK or ADT doesn't have latest Intel® Hardware Accelerated Execution Manager, but you can get it here https://software.intel.com/en-us/android/articles/intel-hardware-accelerated-execution-manager
  4. It is always better to test on real device, Motorola Moto G is as little as £120, also Nexus 7 is very cheap, and for 10" Asus Memo pads are great value for the money. You do not need all these gadgets but one real device makes hell of difference

Thanks for input, I only have an old samsung gt i5500 running android 2.2 at the moment so it's been fun trying to get appcompat7 working so I can test on it :)

When I create a virtual device I get message that I should not give more than 768 MB, I'll try going to 1024, I have 32 bit windows 7 with only 4GB physical.

I believe you can get android 2.3 on my samsung so I might go mad and install that.

Check what is maximum of RAM you can add to your PC. RAM these days is not very expensive and in this case worth upgrade. Company like Crucial can help you with hardware detection and potential memory upgrades

Unfortunately I can only have 4GB of addressable RAM I believe in 32 bit OS :( and not in position to upgrade OS just yet, although should not be too painful in future because CPU is infact 64 bit.

I appreciate you help and advice.

Thank you.

As you may have gathered if you looked at pictures my first app is a very basic calculator.

I'm wondering whether a global variable is appropriate to store a value in, or the clipboard?

I plan to use the clipboard so a sum can be copied for pasting into another app.

Any suggestions are very welcome?

This can be managed by Intents, where your apllication invokes another application and listen for result. Few examples/explanations how calculator can be called by intent can be found here and here You can find more if you search for it ;)

Thank you again peter_budo.

I have a question now regarding making calculations.

I am aware now of intents after you pointing them out, but my goal here is learn how to create an app from scratch rather than use existing app.

I was looking for a general way to make a calculation, and at first thought casting the values entered in my textview to double regardless of whether a precision point was present ot not, and always returning a double. But after a search I read that it will throw an error (doubleformatexeption if I recall) if there is not precision point.

So on further searching I found what is termed BigDecimal type (or is it a class) and wondered if such a type could be used to calculate either int forms or double forms, and this is where I'm getting a bit befuddled.

can't seem to find a laymen example of BigDecimal arithmatic.

So again, any tips are welcome as and when time grants.

Thanks for reading.

I think I got my answer to above, key was to stop using "Android Studio" in my searches and start using "java" instead.

BigDecimal bd1 = new BigDecimal("5");
BigDecimal bd2 = new BigDecimal("5.5");
System.out.println( bd1.add(bd2) );

Also found https://ideone.com/ great resource for quick testing.

I started implementing some code and although it appears to work, I'd love to hear any comments on it since it's my first toe dip into java.

I made a class for globals.
ref: http://androidresearch.wordpress.com/2012/03/22/defining-global-variables-in-android/

public class Globals{
    private static Globals instance;

    // Global variables
    // Stores data that was last in textview
    private BigDecimal data;
    // Stores the last operator button pressed...
    // 1 add: 2 sub: 3 div: 4 mul
    private int lastoperation;

    // Restrict the constructor from being instantiated
    private Globals(){}

    public void setData(BigDecimal d){
        this.data=d;
    }
    public BigDecimal getData(){
        return this.data;
    }

    public void setlastoperation(int o){
        this.lastoperation=o;
    }
    public int getlastoperation(){
        return this.lastoperation;
    }

    public static synchronized Globals getInstance(){
        if(instance==null){
            instance=new Globals();
        }
        return instance;
    }
}

And here is my Main class

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    /* Function handles event when a number button is pressed */
    /* Including decimal point */
    public void numberPressed(View v) {

        Button b = (Button)v;
        TextView textview = (TextView) findViewById(R.id.textView);
        textview.append(b.getText().toString());
    }

    /* Function handles event when "+" button is pressed */
    public void addPressed(View view) {

        Globals g = Globals.getInstance();
        TextView textview = (TextView) findViewById(R.id.textView);
        BigDecimal bd = new BigDecimal(textview.getText().toString());
        g.setData(bd);
        g.setlastoperation(1);
        textview.setText("");
        bd = null;
    }

    /* Function handles event when "=" button is pressed */
    public void equPressed(View view) {

        Globals g = Globals.getInstance();
        TextView textview = (TextView) findViewById(R.id.textView);
        int lastop = g.getlastoperation();
        BigDecimal bdg = new BigDecimal(g.getData().toString());
        BigDecimal bd = new BigDecimal(textview.getText().toString());
        switch (lastop) {
            case 1: {/* "+" button was the last operator button pressed*/
                BigDecimal sum = new BigDecimal(bdg.add(bd).toString());
                textview.setText(sum.toString());
                sum = null;
            }

        }
        bdg = null;
        bd = null;
    }

    /* Function handles event when "clr" (clear) button is pressed */
    public void clrPressed(View view) {

        /* get instance of Globals class and reset the variable to 0 */
        Globals g = Globals.getInstance();
        BigDecimal bd = new BigDecimal(0);
        g.setData(bd);
        bd = null;
        TextView textview = (TextView) findViewById(R.id.textView);
        textview.setText("");
    }
}

What I'm mainly after is advice on simpler ways to do things or things I'm doing wrong that may lead to trouble etc...
Although all comments are very welcome.

Thanks for your time.

Here is update, I added some comments in code and also at the end of post

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import co.uk.apptivation.nga.library.R;

import java.math.BigDecimal;

public class MainActivity extends FragmentActivity { //FragmentActivity is preferred over ActionBarActivity very few apps supports 7 and bellow

    private TextView textview;
    private Globals globals;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textview = (TextView) findViewById(R.id.textView);
        globals = Globals.getInstance();
    }

    /* Function handles event when a number button is pressed */
    /* Including decimal point */
    public void numberPressed(View view) {

        Button button = (Button)view;
        textview.append(button.getText().toString());
    }

    /* Function handles event when "+" button is pressed */
    public void addPressed(View view) {
        //Global now available as class variable no need for creating it
        //Textview now available as class variables
        BigDecimal bd = new BigDecimal(textview.getText().toString());
        globals.setData(bd);
        globals.setlastoperation(1);
        textview.setText("");
        //no need to set local variables to null JVM garbage collector takes care of this
    }

    /* Function handles event when "=" button is pressed */
    public void equPressed(View view) {

        //Global now available as class variable no need for creating it
        //Textview now available as class variables
        int lasTop = globals.getlastoperation();
        BigDecimal bdg = new BigDecimal(globals.getData().toString());
        BigDecimal bd = new BigDecimal(textview.getText().toString());
        switch (lasTop) {
        case 1: {/* "+" button was the last operator button pressed*/
            BigDecimal sum = new BigDecimal(bdg.add(bd).toString());
            textview.setText(sum.toString());
            break; //do not forget to add break otherwise you may for get with next case and your process will felt through case 1 to case 2
        }
        default:
            //May want to add either meaningful log message (NO SYSTEM MESSAGE!!!) or throw exception if situation requires
            break;
        }
    }

    /* Function handles event when "clr" (clear) button is pressed */
    public void clrPressed(View view) {

        /* get instance of Globals class and reset the variable to 0 */
        BigDecimal bd = new BigDecimal(0);
        globals.setData(bd);
        textview.setText("");
    }
}
  • No need to create local variable each time for component from layout. Declaration on create is best way
  • No need to set local variables to null once leaving method JVM garbage collector takes care of it
  • Always give variables proper descriptive names, you may have to return back to project after few months and you will strugle with names like g, v, b,
  • Switch statement should always have default state and there you do some default behaviour, log if unexpected event happend, or throw exception if you have some serious reason to do so
  • Do not use System.out.printl Android has nice and simple logging class

    Log.i(MainActivity.class().getSimpleName(), SOME_MESSAGE); //info
    Log.d(MainActivity.class().getSimpleName(), SOME_MESSAGE); //debug
    Log.w(MainActivity.class().getSimpleName(), SOME_MESSAGE); //warning
    Log.e(MainActivity.class().getSimpleName(), SOME_MESSAGE); //error

Thank's peter_budo, that all makes perfect sense to me.I really appreciate your time and patience.

For the record, I only used System.out.println( bd1.add(bd2) ); for simplicity with online compiler :)

Brilliant comprehensive answer I was looking for.

Back already :(
Having some trouble with replacing trailing 0's in a string.

Problem is, if I do a multiplication operation eg..
100 * 2.12345
it ouputs as 212.34500

I want 212.345

which lead me to...
ref: http://stackoverflow.com/questions/7493273/remove-trailing-decimal-point-zeroes-with-regex

This code does not seem to work though..

BigDecimal sum = new BigDecimal(bdg.multiply(bd).toString());
String parsed = new String(sum.toString().replaceAll("\\.0*$", ""));
textview.setText(parsed);
sum = null;
break;

I still get same output...
212.34500

(edit)

I think it only removes if the 0's fall immediately after . eg...
12.0000

(edit 2)
Thought answer was in post #3 at ref: http://ubuntuforums.org/showthread.php?t=1265804

The java.math.BigDecimal class has a stripTrailingZeros method

And it works with to get what I want here
100 * 2.12345
it ouputs as 212.34500

I want 212.345

but if I enter
10 * 2.00000

I get output of ...
2E+1

Does not nseem correct.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.