I have successfully installed the Eclipse, and Android SDK to my Mac. However when I run the program using the code below. It always gives me the error. "Sorry! The application Hello, Harris(process com.example.helloandroid) has stopped unexpectedly. Please try again.
//package com.example.helloandroid;
import com.example.helloandroid.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello, Harris Family.");
setContentView(tv);
}
}
I think the problem is that you directly set the TextView as the ContentView. You should better use a layout instead.
Is your activity inserted in the application manifest? http://developer.android.com/guide/topics/manifest/activity-element.html
This is because you have not set a layout view, you only have a textview with no parent.
First set up the parent layout for your text view with something like this:
ScrollView sv = new ScrollView(ViewPlay.this);
LinearLayout ll = new LinearLayout(ViewPlay.this);
ll.setOrientation(LinearLayout.VERTICAL);
Then add your text view with :
TextView tv = new TextView(this);
tv.setText("Greetings");
tv.setGravity(Gravity.CENTER_HORIZONTAL);
tv.setTextSize(18);
ll.addView(tv);
Now add the view to the layout with:
this.setContentView(sv);
Adding content to the screen dynamically as above can be very thorny, so where possible use xml.
Related
First I must say that I'm not good in English and "completely new" to Android Programming.
I want to create an app that can monitor server performance. I have use the navigation drawer as my app interface. Each have a few fragment running with different sets of activity. One of the fragment, I would like to create an activity that can calculate the server performance using some if else statement calculation with a button to submit the results. When I run my app, I have trouble with this fragment (FuzFragment) where my app stopped immediately with an error "Unfortunately, ServerMonitorApp has stopped".
Below, is the fragment class (FuzFragment) that I used to display the layout:
package com.example.servermonitorapp;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class FuzFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
LinearLayout mLinearLayout = (LinearLayout) inflater.inflate(R.layout.fragment_fuz,
container, false);
Button sumButton = (Button) mLinearLayout.findViewById(R.id.submitButton);
sumButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText cpu = (EditText) v.findViewById(R.id.textCPU);
EditText ram = (EditText) v.findViewById(R.id.textRAM);
TextView res = (TextView) v.findViewById(R.id.txtResult);
int cpuslow = Integer.parseInt(cpu.getText().toString());
int cpusmedium = Integer.parseInt(cpu.getText().toString());
int cpushigh = Integer.parseInt(cpu.getText().toString());
int ramlow = Integer.parseInt(ram.getText().toString());
int rammedium = Integer.parseInt(ram.getText().toString());
int ramhigh = Integer.parseInt(ram.getText().toString());
if (cpuslow > 0 && cpuslow <= 30 | ramlow > 0 && ramlow <= 23) {
res.setText("Safe");
} else if (cpusmedium > 30 && cpusmedium <= 60 | rammedium > 23 && rammedium <= 38) {
res.setText("Risk");
} else if (cpushigh > 60 | ramhigh > 38) {
res.setText("Very Risk");
} else {
res.setText("Invalid Number");
}
}
});
return mLinearLayout;
}
}
Is there any wrong with my code that can cause my app stopped responding? Need help so much on this since I'm still in learning in Android programming.
Welcome to Android the dark side of development haha ;).
Ok let's go through a few basics.
The onCreate method is used to inflate or draw your layout. prior to having your layout drawn (if you do a findViewById) it won't exist.
In order for the onCreate method to draw the picture it needs the setContent method called that is created by default. This should be one of if not the first line of code you call. It ensures everything is available after that line for UI related interactions of an ACTIVITY. Emphasis on activity because the rules change when you get into fragments.
Now, the next issue is you have bloated code. Doing things like.
EditText myText = findViewById(R.id.myText);
int myValue = Integer.parseInt(myText.getText.toString());
etc.. can all be done in the same line and you are not using the reference to myText anywhere else so just do it like:
int myValue = Integer.parseInt(findViewById(R.id.myText).getText.toString());
Keep in mind I am doing Pseudo code. Please don't be that person that replies with " you have an error in your code " haha or I will not help.
Next up, it appears you never did the setContentView method in your onCreate, please put that back and set the content to your activity.xml code that matches the layout that you are inflating.
Next up, you are doing findViewById inside a button click. This is unnecessary repeat code. If you need to use the textView over and over then store a reference to it to avoid the repetitive lookup.
class MyClass{
EditText myTextBox;
protected void onCreate(stuff){
myTextBox = findViewById(R,id.myTextBox);
findViewById(R.id.myButton).setOnClickListener(new OnClickListener()){
#Override
protected void onClick(){
int myValue = Integer.parseInt(myTextBox.getText().toString());
}
});
}
Also for the record the onCreate should be very clean and to the point. I typically have a syncUI method that does my findViewById calls "prior to data binding days". I don't do that anymore, but new guys learning is fine.
Then in my syncUI I call wrapper methods to handle click listening instead of nesting in onCreate, but for now you are learning. But if you want a quick example..
onCreate(){
setContentView(myViewPointer from the R File);
syncUI();
}
private void syncUI(){
//SETUP TEXTVIEWS OR OTHER UIs that you need
//get btnSubmit reference from findViewByid
btnSubmit_onClick(); //called one time in onCreate to wrap the click listener into method that allows it to collapse and be easily found.
}
private btnSubmit_onClick(){
btnSubmit.setOnClickListener(new OnClickListener(){
#Override
protected void onClick(){
//handle Clicks
}
});
}
Thanks Sam for your reply..
I hv figure out one of my issue that cause my fragment stop responding when I run my app is might due to I mistaken declare my layout as LinearLayout in code above where else my actual layout in the myfragment.xml file is in Relativelayout (shown below).
LinearLayout mLinearLayout = (LinearLayout) inflater.inflate(R.layout.fragment_fuz,
container, false);
After I correct it my app can be open and the fragment related above also able to open. Only there's still problem when I try to run the code using few number sample and my app stop responding with same error "Unfortunately, ServerMonitorApp has stopped".
I have created an activity with two buttons at the top. One button to show "SMS Logs" and second to show "Call Logs".
On clicking "SMS Logs" button, i am dynamically creating textviews and linear layout to show sms logs.
On Clicking "Call Logs", i am dynamically creating another textviews and linear layout to show call logs.
But the problem is that, once if we click "sms log" button and then we click "call log" button, the previously created linear layouts are not removed and the both(previous layouts and the current layouts) are shown simultaneously.
But i want that the previous layouts should be removed on clicking the second button.
Which function, should i use to remove the previous viewgroups or the layouts. Tell me if you need to read my class file.
Edit:
This is my Activity's code,
public class General extends Activity
{
String phone, message;
TextView Logs;
View layout, callLayout;
TextView data, callData, line, callLine;
Button smsLog, callLog;
LinearLayout ll, callll;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.general_main);
Logs = (TextView)findViewById(R.id.Logs);
layout = findViewById(R.id.layout);
callLayout = findViewById(R.id.layout);
smsLog = (Button)findViewById(R.id.smsLogs);
callLog = (Button)findViewById(R.id.callLogs);
smsLog.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
callLayout.setVisibility(View.GONE);
ll = new LinearLayout(getApplicationContext());
ll.setOrientation(LinearLayout.VERTICAL);
data = new TextView(getApplicationContext());
data.setText("First Line");
data.setTextColor(Color.YELLOW);
line = new TextView(getApplicationContext());
line.setText("Second Line");
((ViewGroup) ll).addView(data);
((ViewGroup) layout).addView(line);
((ViewGroup) layout).addView(ll);
}
});
callLog.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
layout.setVisibility(View.GONE);
callll = new LinearLayout(getApplicationContext());
callll.setOrientation(LinearLayout.VERTICAL);
callData = new TextView(getApplicationContext());
callLine = new TextView(getApplicationContext());
callData.setText("Third Line");
callLine.setText("Fourth Line");
((ViewGroup) callll).addView(callData);
((ViewGroup) callLayout).addView(callLine);
((ViewGroup) callLayout).addView(callll);
}
});
}
}
I have removed the extra code and made it simple to understand.
You can use FrameLayout to solve your problem. But I recommend you to use tabview.Here is the link that demonstrates how to develop tabbed applications.Good Luck
You could implement a TabView.
But having your current setup just change the visibility of one view group to GONE and the other to VISIBLE.
GONE will make the view invisible and it won't take up any space anymore.
EDIT based on the code added to the question
Both your layout and callLayout are using the same XML view. Implement 2 identical views in your xml and keep one visible and one gone. This way when you set layout or callLayout visibility to GONE they are 2 different ones not the same. So your onClick() will have something like this:
for smsLog:
layout.setVisibility(View.GONE);
callLayout.setVisibility(View.VISIBLE);
for callLog:
callLayout.setVisibility(View.GONE);
callLayout.setVisibility(View.VISIBLE);
I used to have some experience with developing for android but I started up again after 6 months and forgot most of it. I am now using a macbook to do my developing on and had to set up Eclipse, the Android SDK and AVD all over again and I'm worried I messed something up.
When I start a new project with the default activity that displays "Hello World" on my screen the app runs fine. I then tried to put in two buttons that cause the text in a new TextView to change. But whenever I include the textView part I get a runtime error. When I comment it out, the app runs but obviously nothing happens. Based upon the tutorials I've been reading, this is the appropriate place and way to declare/create the textView but I can't figure out what's wrong. Any suggestions?
[Edit] I was messing around and found that I can make the mytext a field instead of a TextView and that worked. So in my onCreate(), I put
mytext = (TextField)findViewById(R.id.TextView1);
but that doesn't seem the right way to do things.
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class IntroActivity extends Activity {
TextView myText = (TextView)findViewById(R.id.textView1);
//i've tried this with final added on to it as well (recommended by eclipse)
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setButtonClickListener();
}
private void setButtonClickListener() {
Button button1 = (Button)findViewById(R.id.button1);
Button button2 = (Button)findViewById(R.id.button2);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
myText.setText("Hello");
}
});
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// myText.setText("Goodbye");
}
});
}
}
This:
TextView myText = (TextView)findViewById(R.id.textView1);
should be separated. The declaration should be at the same place:
private TextView myText;
But the assignment should come only after setContentView:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myText = (TextView)findViewById(R.id.textView1);
This is done since before setContentView, Dalvik doesn't know from which layout to take the view that matchs the id R.id.textView1
I'm using jason fry's SwipeView, he uses it for imageviews though, I'm struggling to replace it with a layout.
at the moment it works if I replace the ImageView with a TextView but how would I replace the Imageview with a layout
any help is appreciated thanks
package com.example;
import android.graphics.Typeface;
import android.text.Layout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.R;
import uk.co.jasonfry.android.tools.ui.PageControl;
import uk.co.jasonfry.android.tools.ui.SwipeView;
import uk.co.jasonfry.android.tools.ui.SwipeView.OnPageChangedListener;
import android.app.Activity;
import android.os.Bundle;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class MyActivity extends Activity
{
SwipeView mSwipeView;
LinearLayout ll;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ll = new LinearLayout(this);
ll = loadLayout();
PageControl mPageControl = (PageControl) findViewById(R.id.page_control);
mSwipeView = (SwipeView) findViewById(R.id.swipe_view);
//loadImages();
for(int i=0; i<4;i++)
{
mSwipeView.addView(new FrameLayout(this));
}
TextView i0 = new TextView(this);
TextView i1 = new TextView(this);
i0.setText("page 1");
i1.setText("page 2");
((FrameLayout) mSwipeView.getChildContainer().getChildAt(0)).addView(ll);
((FrameLayout) mSwipeView.getChildContainer().getChildAt(1)).addView(ll);
SwipeImageLoader mSwipeImageLoader = new SwipeImageLoader();
mSwipeView.setOnPageChangedListener(mSwipeImageLoader);
mSwipeView.setPageControl(mPageControl);
}
private class SwipeImageLoader implements OnPageChangedListener
{
public void onPageChanged(int oldPage, int newPage)
{
if(newPage>oldPage)//going forwards
{
if(newPage != (mSwipeView.getPageCount()-1))//if at the end, don't load one page after the end
{
TextView v = new TextView(MyActivity.this);
v.setText("page :"+(newPage+1));
((FrameLayout) mSwipeView.getChildContainer().getChildAt(newPage+1)).addView(ll);
}
if(oldPage!=0)//if at the beginning, don't destroy one before the beginning
{
((FrameLayout) mSwipeView.getChildContainer().getChildAt(oldPage-1)).removeAllViews();
}
}
else //going backwards
{
if(newPage!=0)//if at the beginning, don't load one before the beginning
{
TextView v = new TextView(MyActivity.this);
v.setText("page :"+(newPage+1));
((FrameLayout) mSwipeView.getChildContainer().getChildAt(newPage-1)).addView(ll);
}
if(oldPage != (mSwipeView.getPageCount()-1))//if at the end, don't destroy one page after the end
{
((FrameLayout) mSwipeView.getChildContainer().getChildAt(oldPage+1)).removeAllViews();
}
}
}
}
private LinearLayout loadLayout()
{
//logo
ImageView logo = new ImageView(this);
logo.setImageResource(R.drawable.image001);
logo.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
// espace
TextView espace = new TextView(this);
espace.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
espace.setText(" ");
// wrap prest
LinearLayout wprest = new LinearLayout(this);
//Prestation
TextView txt_pres = new TextView(this);
txt_pres.setText(" Prestation n° ");
txt_pres.setTextColor(R.color.black);
// plaid
TextView plaid = new TextView(this);
plaid.setTextColor(R.color.black);
plaid.setTypeface(null, Typeface.BOLD);
plaid.setText("4558");
// -
TextView tiret = new TextView(this);
tiret.setTextColor(R.color.black);
tiret.setTypeface(null, Typeface.BOLD);
tiret.setText(" - ");
// plaid
TextView platyp = new TextView(this);
platyp.setTextColor(R.color.black);
platyp.setTypeface(null, Typeface.BOLD);
platyp.setText("ECHANGE");
wprest.addView(txt_pres);
wprest.addView(plaid);
wprest.addView(tiret);
wprest.addView(platyp);
LinearLayout ll = new LinearLayout(this);
ll.setBackgroundResource(R.color.white);
ll.setOrientation(LinearLayout.VERTICAL);
ll.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
ll.addView(logo);
ll.addView(espace);
ll.addView(wprest);
return ll;
}
}
Why don't you try another ViewPager library, such as:
android-viewflow (https://github.com/pakerfeldt/android-viewflow)
Android-ViewPagerIndicator (https://github.com/JakeWharton/Android-ViewPagerIndicator)
because using it, you can easily custom children layout.
I see it's the most popular ViewPager libraries. For more detail, you can check out my "Android UI Patterns" app on Market: https://market.android.com/details?id=com.groidify.uipatterns. There are many useful samples for developers.
Yo
I use this library all over the place for more than just images. I've used it with complex layouts, so it does work.
I've since added some new layout objects, but not documented them or created examples of how to use them (I'm a busy guy! :p ) One of them is called PageView, it uses an adapter, like a ListView, so if you know how to use a ListView you should be able to use this. The key is using the .setAdapter(BaseAdapter adapter) method.
Make sure you're using the latest one from github. Here's a link straight to the PageView class code on github: https://github.com/fry15/uk.co.jasonfry.android.tools/blob/master/src/uk/co/jasonfry/android/tools/widget/PageView.java
I have a image button and i want that image button when pressed it changes the text in a textbox and it changes a image to a different image how do i do this?
You need an OnClickListener: http://developer.android.com/reference/android/view/View.OnClickListener.html
When clicked your text can be changed with (something like) text.setText("new text");
I'll find a link in a minute which will help more.
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
public class TestesetetActivity extends Activity {
/** Called when the activity is first created. */
TextView textview = null;
ImageButton buttonResume = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonResume = (ImageButton) findViewById(R.id.imageButton1);
textview = (TextView) findViewById(R.id.textView1);
buttonResume.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
textview.setText("test");
buttonResume.setImageResource(R.drawable.push_pin);
}
});
}
}
In the xml file, you can give the image an onClick attribute, which calls a method in the java class, which calls the xml resource, and passes it the id of the ImageView.
In that java method, you can use
((ImageView) view).setImageResource(int id)
or
setImageDrawable(Drawable d)
to change the image.
Likewise, you can identify the TextView you wish to change using, for example,
TextView tv = (TextView) findViewById( id )
with id being the id of the TextView you wish to find.
You can then use
tv.setText(String s)
to set the text in this view.
In your OnClickListener, you could use
button.setBackgroundResource(YOUR_BUTTON_ID);
or
button.setImageResource(YOUR_BUTTON_ID);