I am attempting to make a simple android app that calculates the diameter of a sonar signal. The user inputs the depth(in meters) and angle(in degrees) and the app inputs the information into the formula:
2.0 * depth * Math.tan(angle / 2.0)
So I have created the UI and the java code and when I go to run the app in a VM it loads, I enter numbers in to test it, and when I hit the calculate button it does nothing. I am new to java and android development in general so if anyone could shed some light that would be great.
Here is the MainActivity.java
XML file for the UI widgets activity_main.xml
I suspect the problem is something to do with this code that includes the formula but I am not sure so any help would be greatly appreciated:
double depth1 = Integer.parseInt(depth.getText().toString());
double angle1 = Integer.parseInt(angle.getText().toString());
double result1 = 2.0 * depth1 * Math.tan(angle1 / 2.0);
result.setText(valueOf(result1));
It does nothing because you have added onClickListener on TextView instead of the Button here:
result.setOnClickListener(...)
You just need to change it to this:
// instance of your button
cal.setOnClickListener(...)
You are using the clicklistener of your result view, that is why the value is not displayed on clicking on the cal view (calculate button). Try the following.
cal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//converting the user input from a string to an integer for calculation
double depth1 = Integer.parseInt(depth.getText().toString());
double angle1 = Integer.parseInt(angle.getText().toString());
double result1 = 2.0 * depth1 * Math.tan(angle1 / 2.0);
result.setText(String.valueOf(result1));
}
});
We use setOnContextClickListener to register a callback to be invoked when this view is context clicked. If the view is not context clickable, it becomes context clickable.
So, as mentioned above, insteasd
result.setOnClickListener(...)
use
cal.setOnClickListener(...)
Please refer:
https://developer.android.com/reference/android/view/View.html#setOnContextClickListener(android.view.View.OnContextClickListener)
I am using jeremy feinstein's SlidingMenu for an Android app. When the left menu is opened, I still have a remaining space from the behind view uncovered. In that remaining view I have a button that I want to handle onClick. But when I click on it or in any other part of the view, it just closes the left menu.
How can I make this work? I tried to set sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN|SlidingMenu.TOUCHMODE_FULLSCREEN); but it didn't work this way. This is the code for my SlidingMenu object:
SlidingMenu sm = getSlidingMenu();
sm.setShadowWidthRes(R.dimen.shadow_width);
sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
sm.setFadeDegree(0.0f);
sm.setMode(SlidingMenu.LEFT_RIGHT);
sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN|SlidingMenu.TOUCHMODE_FULLSCREEN);
// set the left menu
sm.setMenu(R.layout.menu_frame_left);
getSupportFragmentManager().beginTransaction()
.replace(R.id.menu_frame_left, new LeftMenuListFragment())
.commit();
// set the right menu
sm.setSecondaryMenu(R.layout.menu_frame_right);
getSupportFragmentManager().beginTransaction()
.replace(R.id.menu_frame_right, new RightMenuListFragment())
.commit();
I will also attach an image drawn by me to explain better what I am trying to achieve:
Based on the code of jeremy feinstein's SlidingMenu, I found number value on the constant value for use with setTouchModeAbove() :
/** Constant value for use with setTouchModeAbove(). Allows the SlidingMenu to be opened with a swipe
* gesture on the screen's margin
*/
public static final int TOUCHMODE_MARGIN = 0;
/** Constant value for use with setTouchModeAbove(). Allows the SlidingMenu to be opened with a swipe
* gesture anywhere on the screen
*/
public static final int TOUCHMODE_FULLSCREEN = 1;
while you set sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN|SlidingMenu.TOUCHMODE_FULLSCREEN); ,in fact the vaule of touchModeAbobe is 1|0 that equal 1 .
I suggest you try sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);,it may work.
I have a TableViewer with a ComboBoxCellEditor. When I click into the cell, first I get a text box (similar to the TextCellEditor) with an arrow next to it. If I click the arrow, I get the drop down list with the values I put into it.
Is there any way for me to skip the text box step? I want it to open up the combo box right away when I click/traverse into the cell. Hand in hand with this is that I also don't want to allow any options other than the ones in the list.
I thought maybe this behavior is controlled by a style, but the only styles I found were
/**
* The list is dropped down when the activation is done through the mouse
*/
public static final int DROP_DOWN_ON_MOUSE_ACTIVATION = 1;
/**
* The list is dropped down when the activation is done through the keyboard
*/
public static final int DROP_DOWN_ON_KEY_ACTIVATION = 1 << 1;
/**
* The list is dropped down when the activation is done without
* ui-interaction
*/
public static final int DROP_DOWN_ON_PROGRAMMATIC_ACTIVATION = 1 << 2;
/**
* The list is dropped down when the activation is done by traversing from
* cell to cell
*/
public static final int DROP_DOWN_ON_TRAVERSE_ACTIVATION = 1 << 3;
and they didn't seem to be relevant. In fact, I set all of them, and I wasn't able to get the functionality I'm looking for.
How can I have the dropbox show without having the accompanying text box?
It's possible to change the styling of the underlying Combo widget by using the constructor:
ComboBoxCellEditor(Composite parent, String[] items, int style)
and passing SWT.READ_ONLY as style
I have a GridView which contains several items. By clicking an item a new detail view is created. Then by clicking back button user is returned to GridView. I want to preserve exact scroll position and I have accomplished that with following code:
Creating GridView
mArtistList = (GridView) artistsView.findViewById(R.id.gridview);
mArtistAdapter = new ArtistAdapter(mContext);
mArtistList.setAdapter(mArtistAdapter);
// Adapter gets items asynchronously
mArtistAdapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged () {
// setting first selection item
mArtistList.setSelection(sActiveItem);
/*
*
* PROBLEM HERE
* Works ok, but when user touches the GridView
* scroll position jumps to position where it
* would be without this line.
*
*/
mArtistList.scrollBy(0, sActiveTop);
super.onChanged();
}
});
When user clicks an item on GridView
sActiveItem = mArtistList.getFirstVisiblePosition();
// vertical spacing (5dp to pixels)
sActiveTop = (int) (5.0f * getResources().getDisplayMetrics().density);
View firstItem = mArtistList.getChildAt(0);
if (firstItem != null) {
sActiveTop -= firstItem.getTop();
}
This works fine. Scroll position is exactly right after back button is pressed. The problem comes when user touches GridView. Scroll jumps to position where the first visible item is exactly at top of screen. How can I prevent this jump?
I don't speak english as my native language, so my explanation might be hard to understand. That's why I draw an image to indicate the problem:
I am trying to create an generic API that run on-top of iText. One of the function of this API is to allow the user to split the PDF to invidual page, and allow the user to add list of text onto each pdf page after the split. For example, a pdf of 20 pages, and after run this process, I will have 20 of 1-page-pdf, and the first pdf will have a text 000001 on it, and the last pdf will have 000020 on it pdf. So to accomplish this, I use abstract method that allow the developer to write code on how they want the text to format given the current page number.
public abstract class GenericText {
/**
* The X position of the text. (0, 0) is at the bottom left
*/
private float x;
/**
* The Y position of the text. (0, 0) is at the bottom left
*/
private float y;
/**
* The rotation of the text. Rotation 0, 90, 180, 270
*/
private float rotation;
/**
* <code>com.itextpdf.text.pdf.BaseFont</code>. Determine the font for the text
*/
private BaseFont font;
/**
* Determine the font size of the text
*/
private float fontSize;
/**
* This tells whether text can only be placed first page or on every page
*/
private ComponentPlacement placement;
/**
* Since the text that the user want to insert onto the Pdf might vary
* from page to page, or from logical document to logical document, we allow
* the user to write their own implementation of the text. To give the user enough
* flexibility, we give them the reference to the physical page index, the logical page index.
* #param physcialPage The actual page number that the user current looking at
* #param logicalPage A Pdf might contain multiples sub-documents, <code>logicalPage</code>
* tell the user which logical sub-document the system currently looking at
*/
public abstract String generateText(int physicalPage, int logicalPage);
...
}
PdfPrcessor.java: This is where the split happen
/**
* This is the main process that will split the pdf into individual page, and text to each page
*/
public void splitPdf(String inputPdf, boolean isSplit, List<GenericText> textList,
String outputDir, String baseOutputName, String outputPdfName) throws IOException, DocumentException{
...
PdfReader reader = new PdfReader(inputPdf)
PdfContentByte cb = ... ;
for(int physicalPageIndex=1 ; physicalPageIndex<=reader.getNumberOfPages(); physicalPageIndex ++)
...
//Code to split PDF. Write each page to a separate pdf. For each pdf, insert all text inside `textList` onto the pdf
...
//Insert text
if(textList != null){
for(GenericText textComponent : textList){
String text = textComponent.generateText(physicalPageIndex, logicalPageIndex);
addText(text, cb, textComponent.getFont(), textComponent.getFontSize(), textComponent.getX(), textComponent.getY(), textComponent.getRotation());
}
}
}
...
}
So in my main class I would do this,
final String printName = printNameLookup.get(baseOutputName);
final String seq = config.getPrintJobSeq();
GenericText keyline = new GenericText(90, 640, 0, arial, 7, ComponentPlacement.FIRST_PAGE){
#Override
public String generateText(int physicalPage, int logicalPage) {
return printName + seq + " " + Utils.right(String.valueOf(logicalPage), 6, '0');
}
};
textList.add(keyline);
pdfProcess.splitPdf(inputPdfPath, true, textList, outputDir, baseOutputName, outputPdfName);
This work great, and I think it is very flexible however, printName and seq has be be declared as final in order to pass inside generateText(int physicalPage, int logicalPage). How do I design this so that it wont require final field. Will interface help? I use guava API, and I can do this
ImmutableListMultimap<String, File> groups = Multimaps.index(pdfList,
new Function<File, String>(){
public String apply(File input){
String[] ids = getId(input.getName());
PackageLog pl = logProcessor.lookUp(new Long(ids[0]), ids[1]);
String printName = printNameLookup.get(getPackageName(pl, s));
}
});
logProcessor and printNameLookup is not final, I like the way they design, and I am reading their sources now, but it will take some times, anyone with expert on design knowledge can shed me some light?
Copy them into a final variables and use those instead.
String printName = printNameLookup.get(baseOutputName);
String seq = config.getPrintJobSeq();
// use these in the anonymous class.
final String finalPrintName = printName;
final String finalSeq = seq;
or use arrays
final String[] printName = { printNameLookup.get(baseOutputName) };
final String[] seq = { config.getPrintJobSeq() };
// use printName[0] and seq[0] everywhere.
You have discovered the Template Method design pattern. In this case copying the values into final variables will work.