Closed danvim closed 7 years ago
package dcheungaa.procal;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.ActionBar;
import android.view.Display;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.appindexing.Thing;
import com.google.android.gms.common.api.GoogleApiClient;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private int width,height;
private RelativeLayout contentMain;
private LinearLayout llScreen;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);*/
/*FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});*/
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, /*toolbar,*/ R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
TextView matrixDisplay = (TextView) findViewById(R.id.matrixDisplay);
final Typeface FONT_FX50 = Typeface.createFromAsset(getAssets(), "fonts/Fx50.otf");
matrixDisplay.setTypeface(FONT_FX50);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return true;
} else if (id == R.id.nav_save) {
} else if (id == R.id.nav_history) {
} else if (id == R.id.nav_share) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
public Action getIndexApiAction() {
Thing object = new Thing.Builder()
.setName("Main Page") // TODO: Define a title for the content shown.
// TODO: Make sure this auto-generated URL is correct.
.setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
.build();
return new Action.Builder(Action.TYPE_VIEW)
.setObject(object)
.setActionStatus(Action.STATUS_TYPE_COMPLETED)
.build();
}
@Override
public void onStart() {
super.onStart();
int max;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
contentMain = (RelativeLayout) findViewById(R.id.content_main);
llScreen = (LinearLayout) findViewById(R.id.llScreen);
LinearLayout upper=llScreen;
Button preBtn;
for (int i=0 ;i<6 ; i++){
LinearLayout row = new LinearLayout(this);
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
if (i==0) rlp.addRule(RelativeLayout.BELOW,R.id.llScreen);
else rlp.addRule(RelativeLayout.BELOW,upper.getId());
row.setLayoutParams(rlp);
Button btn= new Button(this);
preBtn = btn;
if (i<3) max=6;
else max=5;
for (int j=0; j<max ; j++){
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
if (j==0) lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
else lp.addRule(RelativeLayout.RIGHT_OF,preBtn.getId());
preBtn = btn;
btn.setLayoutParams(lp);
btn.getLayoutParams().width=width/max;
btn.setId(i*10+j);
btn.setText(Integer.toString(10*i+j)+" "+Integer.toString(btn.getMinWidth()));
row.addView(btn);
if (j<6)btn= new Button(this);
}
contentMain.addView(row);
row.setId(i+1);
upper=row;
}
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
AppIndex.AppIndexApi.start(client, getIndexApiAction());
}
@Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
AppIndex.AppIndexApi.end(client, getIndexApiAction());
client.disconnect();
}
}
linearLayout llButtonPanel was commented
@dipsywong98 Can you explain your code and excerpt the necessary code to make it more concise?
get screen size
Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int width = size.x; int height = size.y;
set button width
btn.getLayoutParams().width=width/max;
finally done T.T
//color define here
//I dunno why color in res was loaded with wrong color
private int colorAccent=Color.parseColor("#FF9800"); //<--
private int colorPurple=Color.parseColor("#C51162"); //<--
//use this listener to get the height of llScreen and matrixdiplay
//if use oncreate, height will be 0 as they are still not well defined by the program
@Override
public void onWindowFocusChanged(boolean hasFocus) { //<--
super.onWindowFocusChanged(hasFocus); //<--
//get windows' height and width
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
//define the elements defined in layout
TextView tv = (TextView)findViewById(R.id.matrixDisplay); //<--
contentMain = (RelativeLayout) findViewById(R.id.content_main);
llScreen = (LinearLayout) findViewById(R.id.llScreen);
//the height of space left to place keyboard
int rows_height=height-llScreen.getHeight()-findViewById(R.id.matrixDisplay).getHeight(); //<--
//define the height of two types of button, fn : large = 3.8 : 4.5
double btn_large_height= rows_height*4.5/8.3/4; //<--
double btn_fn_height = rows_height*3.8/8.3/4; //<--
//for debug, display the height of two types of button
// tv.setText("("+width+","+height+") ("+btn_large_height+","+btn_fn_height+")"); //<--
LinearLayout rows = (LinearLayout) findViewById(R.id.rows); //<--
rows.setOrientation(LinearLayout.VERTICAL); //<--
String json = "";
InputStream in_s = getResources().openRawResource(R.raw.keypad);
try {
byte[] b = new byte[in_s.available()];
in_s.read(b);
json = new String(b);
} catch (IOException e) {
}
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
Gson gson=new Gson();
JsonHelper.KeypadRows keypadRows = gson.fromJson(jsonObject, JsonHelper.KeypadRows.class);
for (JsonHelper.Key[] keys : keypadRows.rows) {
LinearLayout row = new LinearLayout(this);
row.setOrientation(LinearLayout.HORIZONTAL);
row.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
for (JsonHelper.Key key : keys) {
Button btn = new Button(this);
//apply styles defined in json
btn.setText(key.key);
if (key.style.contains("Orange")) btn.setTextColor(colorAccent); //<--change color
else if (key.style.contains("Purple")) btn.setTextColor(colorPurple); //<--change color
btn.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1f));//our honorable leader Daniel's code
if (key.style.contains("Large")) btn.getLayoutParams().height = (int)btn_large_height ; //<--set height of button Large
if (key.style.contains("Fn")) btn.getLayoutParams().height = (int)btn_fn_height ; //<--set height of button Fn
btn.getLayoutParams().width = (int) width/keys.length; //<--set btn width, btn width may change after changing the height
btn.setGravity(Gravity.CENTER); //<--align to the center
row.addView(btn);
final Button fbtn=btn; //<--for passing btn into the listener function for dynamic padding
//listener to hear if the button text take more than 1 line, if yes, decrease the padding to see if fit to 1 line
btn.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { //<--set listener to the btn
@Override //<--
public void onGlobalLayout() { //<--define listener function
//if take more than 1 line
if (fbtn.getLineCount()>1){ //<--check if text in btn more than 1 line
//shrink padding
fbtn.setPadding(fbtn.getPaddingLeft()-1,fbtn.getPaddingTop(),fbtn.getPaddingRight()-1,fbtn.getPaddingBottom()); //<--shrink padding
} //<--
// if already take 1 line only, remove the listener //<--
else fbtn.getViewTreeObserver().removeGlobalOnLayoutListener(this); //<--
} //<--
}); //<--
}
rows.addView(row);
}
}
//on start is almost useless now
@Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
AppIndex.AppIndexApi.start(client, getIndexApiAction());
}
I amend the keys in JSON to make it look more beautiful
{
"rows":[
[
{
"key": "SHIFT",
"style": "Fn"
},
{
"key": "ALPHA",
"style": "Fn"
},
{
"key": "CONST",
"style": "Fn"
},
{
"key": "MDOE",
"style": "Fn"
},
{
"key": "d/dx",
"style": "Fn",
"shift": "integration"
},
{
"key": "FUNC",
"style": "Fn_Orange"
}
],
[
{
"key": "a b/c",
"style": "Fn",
"shift": "d/c"
},
{
"key": "√",
"style": "Fn"
},
{
"key": "x^2",
"style": "Fn"
},
{
"key": "^",
"style": "Fn",
"shift": "x_root"
},
{
"key": "log",
"style": "Fn",
"shift": "10^x"
},
{
"key": "ln",
"style": "Fn",
"shift": "e^x"
}
],
[
{
"key": "(-)",
"style": "Fn",
"shift": "angle"
},
{
"key": "° ' \"",
"style": "Fn",
"shift": "<-"
},
{
"key": "hyp",
"style": "Fn"
},
{
"key": "sin",
"style": "Fn",
"shift": "asin"
},
{
"key": "cos",
"style": "Fn",
"shift": "acos"
},
{
"key": "tan",
"style": "Fn",
"shift": "atan"
}
],
[
{
"key": "REC",
"style": "Fn",
"shift": "str"
},
{
"key": "ENG",
"style": "Fn",
"shift": "<-"
},
{
"key": "(",
"style": "Fn",
"shift": "%"
},
{
"key": ")",
"style": "Fn",
"shift": "abs"
},
{
"key": ",",
"style": "Fn",
"shift": ";"
},
{
"key": "M+",
"style": "Fn",
"shift": "M-"
}
],
[
{
"key": "7",
"style": "Large_More",
"shift": "constant"
},
{
"key": "8",
"style": "Large"
},
{
"key": "9",
"style": "Large_More",
"shift": "clear"
},
{
"key": "DEL",
"style": "Purple_Large_Text_More",
"shift": "ins"
},
{
"key": "AC",
"style": "Purple_Large_Text"
}
],
[
{
"key": "4",
"style": "Large"
},
{
"key": "5",
"style": "Large"
},
{
"key": "6",
"style": "Large"
},
{
"key": "✘",
"style": "Large",
"shift": "nPr"
},
{
"key": "/",
"style": "Large",
"shift": "nCr"
}
],
[
{
"key": "1",
"style": "Large"
},
{
"key": "2",
"style": "Large"
},
{
"key": "3",
"style": "Large"
},
{
"key": "+",
"style": "Large",
"shift": "pol"
},
{
"key": "-",
"style": "Large",
"shift": "rec"
}
],
[
{
"key": "0",
"style": "Large",
"shift": "rnd"
},
{
"key": ".",
"style": "Large",
"shift": "ran"
},
{
"key": "EXP",
"style": "Large_Text",
"shift": "pi"
},
{
"key": "ANS",
"style": "Large_Text",
"shift": "DRG"
},
{
"key": "EXE",
"style": "Large_Text"
}
]
]
}
@dipsywong98 can you mark the line changed with comments, like: //<--
after that line?
basic dynamic layout done in fa00abf87b46dc1f618fdb309b1d7b71e7d94571
alignment of ... above the button can be improved
Add code to dynamically resize layouts to fit screen size