Is it possible to initialize all UI elements of certain type (like all TextViews or all LineraLayouts or ...) in a some kind of loop?
I have many layouts with a lot of the elements of the same type and it's really painful to do it all just by typing.
You can use RoboGuice .It doesn't use loops, but helps you to Inject your View, Resource, System Service, or any other object in to your code.
RoboGuice is a framework that brings the simplicity and ease of Dependency Injection to Android, using Google's own Guice library.
To give you an idea, take a look at this simple example of a typical Android activity:
class AndroidWay extends Activity {
TextView name;
ImageView thumbnail;
LocationManager loc;
Drawable icon;
String myName;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name = (TextView) findViewById(R.id.name);
thumbnail = (ImageView) findViewById(R.id.thumbnail);
loc = (LocationManager) getSystemService(Activity.LOCATION_SERVICE);
icon = getResources().getDrawable(R.drawable.icon);
myName = getString(R.string.app_name);
name.setText( "Hello, " + myName );
}
}
This example is 19 lines of code. If you're trying to read through onCreate(), you have to skip over 5 lines of boilerplate initialization to find the only one that really matters: name.setText(). And complex activities can end up with a lot more of this sort of initialization code.
Compare this to the same app, written using RoboGuice:
class RoboWay extends RoboActivity {
#InjectView(R.id.name) TextView name;
#InjectView(R.id.thumbnail) ImageView thumbnail;
#InjectResource(R.drawable.icon) Drawable icon;
#InjectResource(R.string.app_name) String myName;
#Inject LocationManager loc;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name.setText( "Hello, " + myName );
}
}
In this example, onCreate() is much easier to take in at a glance. All the platform boilerplate is stripped away and you're left with just your own app's business logic. Do you need a SystemService? Inject one. Do you need a View or Resource? Inject those, too, and RoboGuice will take care of the details.
RoboGuice's goal is to make your code be about your app, rather than be about all the initialization and lifecycle code you typically have to maintain in Android.
This text is from here
I have/had done something similar. Just for your reference, here's the code:
public class AbcActivity extends Activity
{
protected boolean changesPending;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login_screen);
setViews(); //this method is created and called to take care of the buttons and edittext fields, and can probably hold a number of other fields/widgets as well
}
/** Take care of the Buttons and EditTexts here*/
private void setViews()
{
EditText userEdit = (EditText)findViewById(R.id.editText1);
EditText passwordEdit = (EditText)findViewById(R.id.editText2);
Button loginButton = (Button)findViewById(R.id.login_button);
loginButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
login(); // some random method
}
});
Button cancelButton = (Button)findViewById(R.id.cancel_button);
cancelButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
cancel(); //another random method
}
});
userEdit.addTextChangedListener(new TextWatcher()
{
public void onTextChanged(CharSequence s, int start, int before, int count)
{
changesPending = true;
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void afterTextChanged(Editable s) {}
});
passwordEdit.addTextChangedListener(new TextWatcher()
{
public void onTextChanged(CharSequence s, int start, int before, int count)
{
changesPending = true;
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void afterTextChanged(Editable s) {}
});
}
}
Hope this helps.
If you are trying to handle a large number of Views it may be worthwhile handling creation of these Views at runtime, attaching them to the relevant container. For example:
ViewGroup container = (ViewGroup) findViewById(R.id.container);
for(int i = 0; i < NUM_TEXT_VIEWS; i++){
TextView tv = new TextView(this); // where 'this' is your Activity
tv.setText("This is TextView " + i);
container.addView(tv);
}
Properties set in your xml file for a View usually have a corresponding Java method call.
Related
I want to be able to store the contents of the editText input, then be able to display it in a listview.
I have connected a RFID device that is set in emulator mode. This mode basically also you to scan an RFID tag and the RFID number gets populated where ever the mouse cursor is. In this case it is at the editText input. The lenght of the RFID number is 10, since the RFID number as 10 digits. Once the RFID number is detected I then want to display it on the listview and scan another tag and add that to the listview also.
In my case whenever I code sees the display method the app crashes and I dont know why. Can someone explain to me why this is happening?
epc.add("\n" + etRfidNo.getText().toString() + ", " + DateFormat.getInstance().format(currentDate));
display();```
MainActivity code:
public class MainActivity extends AppCompatActivity {
EditText etRfidNo;
TextView textView;
private Set<String> epc = new HashSet<>();
ArrayAdapter<String> contactAdapter;
String single_epc;
Button scan;
ListView listView;
boolean set = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.textView);
etRfidNo = (EditText) findViewById(R.id.etRfidNo);
scan = (Button) findViewById(R.id.scan);
TextView textV = (TextView)findViewById(R.id.textView);
etRfidNo.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//TextView textV = (TextView)findViewById(R.id.textView);
//textV.setText(s); //set text for text view
single_epc = String.valueOf(s);
if(s.length() == 10)
{
Date currentDate = new Date();
epc.add("\n" + etRfidNo.getText().toString() + ", " + DateFormat.getInstance().format(currentDate));
display();
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
public void display() {
contactAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<>(epc));
listView.setAdapter(contactAdapter);
}
}
listView = (ListView) findViewById(R.id.listviewID);
Forgot to add this.
I'm trying to notifydatasetchanged when I've finished to edit an edit text in a recyclerview (why ? because some others objects in recyclerview are accessible only if for exemple the edit text is equals to "test").
So I have an adapter with many view Holders, here is the one for edit text:
public EditTextViewHolder(View itemView, final Activity activity, final Context context, final String param) {
super(itemView);
this.activity = activity;
this.context = context;
this.param = param;
name = (TextView) itemView.findViewById(R.id.tEditTextName);
desc = (TextView) itemView.findViewById(R.id.tEditTextDescription);
details = (TextView) itemView.findViewById(R.id.tEditTextMoreDetails);
editText = (EditText) itemView.findViewById(R.id.eEditTextValue);
image = (ImageView) itemView.findViewById(R.id.iEditTextImage);
lMain = (LinearLayout) itemView.findViewById(R.id.layoutTaskEditText);
lOptional = (LinearLayout) itemView.findViewById(R.id.layoutEditTextOptional);
lRequired = (LinearLayout) itemView.findViewById(R.id.isRequiredTask);
}
public void setLayout(final Content content) {
name.setText(content.getTitle());
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
content.getAnswers().get(0).setValue(s.toString().trim());
}
});
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus)
TaskActivity.sAdapter.notifyDataSetChanged();
}
});
}
But I'm getting the error "Cannot call this method while RecyclerView is computing a layout or scrolling" even if I try to notify in handler or on ui thread it's not working.
It works with all my others view holders. Do you know what am I doing wrong with edit text ?
This exception probably occur when you are calling
notifyItemInserted(position);, notifyItemChanged(position), or
notifyItemRemoved(position); from a background thread (or from a
callback, which runs on a background thread).
To solve this, use Handler in UI Thread:
android.os.Handler mHandler = getActivity().getWindow().getDecorView().getHandler();
mHandler.post(new Runnable() {
public void run(){
//change adapter contents
mRecyclerViewAdapter.notifyItemInserted(position);
}
});
try to call notifyDataSetChanged on adapter instead of activity and also call it inside on UIThread.
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
and make sure inside your adapter has this method with right number of data
#Override
public int getItemCount() {
}
I have an app with 3 activities,home,calculationResult and help.What I'm trying to do is save the details of the calculations on calculationResult when the user navigates to help.So when the user is in help and presses the action bar back icon,the results of the calculation will still be there in calculationResult.
I have tried to implement this so far by following this guide: Recreating an activity,But when I implemented it the variable I'm wanting to store is not recognized when using with savedInstanceState.Below is how I have tried to do this in the result class.Can someone point out where I have gone wrong with this or if this is the correct way to accomplish saving the activity state?
public class CalcResult extends Activity implements OnClickListener{
TextView result1;
static final String MARK1 = "marking1";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
if (savedInstanceState != null) {
// Restore value of members from saved state
//not recognizing this variable mark1 which I'm setting to the variable that stores the result of the calculation.
mark1 = savedInstanceState.getDouble(MARK1);
}
final Intent intent1=new Intent(this,AboutActivity.class);
final Intent intent2=new Intent(this,MainActivity.class);
final Intent intent3=new Intent(this,MainActivity.class);
final ViewGroup actionBarLayout = (ViewGroup) getLayoutInflater().inflate(
R.layout.a,
null);
// Set up your ActionBar
final ActionBar actionBar = getActionBar();
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setCustomView(actionBarLayout);
final Button actionBarHome = (Button) findViewById(R.id.action_bar_title);
actionBarHome.setBackgroundResource(R.drawable.ic_action_back);
actionBarHome.setOnClickListener(this);
actionBarHome.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(intent2);
}
});
final Button actionBarInfo = (Button) findViewById(R.id.action_bar_staff);
actionBarInfo.setBackgroundResource(R.drawable.ic_action_help);
actionBarInfo.setOnClickListener(this);
actionBarInfo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(intent1);
}
});
final Button actionBarHoome = (Button) findViewById(R.id.action_bar_home);
actionBarHoome.setBackgroundResource(R.drawable.appicon);
actionBarHoome.setOnClickListener(this);
actionBarHoome.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(intent3);
}
});
result1 = (TextView)findViewById(R.id.markOne);
Intent intent = getIntent();
double markOne = intent.getDoubleExtra("number1", 0);
DecimalFormat df = new DecimalFormat("#.##");
result1.setText(String.valueOf(df.format(markOne)+"mm"));
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
//Also doesn't recognise markOne here ->
savedInstanceState.putDouble(MARK1, this.markOne);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
Instead of this
double markOne = intent.getDoubleExtra("number1", 0);
You should write
markOne = intent.getDoubleExtra("number1", 0);
by declaring it again you are not assigning the value to the class level markOne
Also you can try setting the lauchmode of your calculateResult activity as singleTop
android:launchMode="singleTop"
This will use the same instance of the activity that already exist on the top of the stack so will have the same state as before.
Try calling finish in your Help activity when you move to CalculationResult activity.
for ex:
StartActivity(<Intent>);
finish();
onRestoreInstanceState() is called when Activity was killed by the OS. "Such situation happen when:
•orientation of the device changes (your activity is destroyed and recreated)
•there is another activity in front of yours and at some point the OS kills your activity in order to free memory.
Next time when you start your activity onRestoreInstanceState() will be called."
But in your case, this might not happen.
Approach i followed
I set a global varibale to act as a flag if i am launching this activity for the first time. If the global varibale is the same as what i had set, i leave the editText untouched. (in your case, result1). If the value is changed, i set the editText for this value. If the user clicks the editText even once, i track the change and store the value. When you think, the mark1 is no longer needed, you can set the value of flag again as "FIRSTENTRY". This would work.
Kindly try and let us know if you still face issues.
Step 1
Created a class to store a static Global variable.
public class Constants {
public static String sFlag= "FIRSTENTRY";
}
Step 2
Add this piece of code after "setContentView(R.layout.result);" line in your oncreate method. Instead of TextView, i have declared result1 as EditText.
if(!Constants.sFlag.equalsIgnoreCase("FIRSTENTRY"))
{
result1.setText(Constants.sFlag);
}
result1.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
Constants.sFlag = result1.getText().toString();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Constants.sFlag = result1.getText().toString();
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
Constants.sFlag = result1.getText().toString();
}
});
So I'm in a basic part of my application I'm wanting to make. I've never gotten this error before, and I don't know what's going on. My .setText is throwing an error saying "setText cannot be resolved or is not a field" I've looked around and haven't been able to find my problem. I believe I'm doing it correctly. If anyone could help me out that'd be great!
MainActivity.java:
public class MainActivity extends Activity {
final TextView loading_Text = (TextView)findViewById(R.id.textView4);
final EditText name_Edit = (EditText)findViewById(R.id.editText1);
//String Values
String Age="";
String Name = name_Edit.getText().toString();
//Int Values
int Gender = 0; //1 male | 2 female
int Group = 0; //Different groups for ages and genders
int save_Info = 0; //save info to phone
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button male_Button= (Button)findViewById(R.id.button1);
Button female_Button = (Button)findViewById(R.id.button2);
male_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Gender++;//Adds one to show this user is a male.
loading_Text.setText=(Name);
}
});
}
I saw two problems:
First:
loading_Text.setText=(Name);
Should be
loading_Text.setText("The text you want to set");
You'll need to take a look at the API document to see how to call the method.
Second:
Move these part:
final TextView loading_Text = (TextView)findViewById(R.id.textView4);
final EditText name_Edit = (EditText)findViewById(R.id.editText1);
//String Values
String Age="";
String Name = name_Edit.getText().toString();
inside your onCreate, like this:
public class MainActivity extends Activity {
TextView loading_Text;
EditText name_Edit;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loading_Text = (TextView)findViewById(R.id.textView4);
name_Edit = (EditText)findViewById(R.id.editText1);
Or you'll get NullPointerException.
This is because you were trying to reach the View's property before the view is being initialized. View will be initialized after setContentView, and what you were intend to do was findViewById from R.layout.activity_main before it had been loaded.
Similarly, you'll need to move this call of method:
String Name = name_Edit.getText().toString();
somewhere after setContentView.
setText is a function. So you would need to pass name as a argument.
like loading_Text.setText(Name);
Change
loading_Text.setText=(Name);
to this:
loading_Text.setText(Name);
Also, if you don't see anything in the textview, it is because you are getting the edittext's text before you even create your views, I use an on edittext listener like this to refresh the String when the edit text is changed:
name_Edit.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Name = name_Edit.getText().toString();
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
I hope this works for you :)
Ok,so I"m trying to make a Currency Converter between dollars and euros based on a tutorial I found on the web.The problem is that the tutorial is relying on 2 radio buttons to switch between the conversion, a reference for order stating to the program which method to call first.I want the program to make that conversion independetly from the two radio buttons and instantaneously,for instance if I write a number in the euro or dollar editText view...then clicking on the convert button will make the appropriate conversion.But I cannot because there are 2 methods and unless a have a way to display their input simultaneously it won't work.So my question is how ca I update the two editText views simultaneously when I press the convert button?Thank you
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class ConvertorActivity extends Activity {
TextView dollars;
TextView euros;
Button convert;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
dollars = (TextView)this.findViewById(R.id.dollars);
euros = (TextView)this.findViewById(R.id.euros);
convert = (Button)this.findViewById(R.id.convert);
convert.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
convertBoth();
}
});
}
public void convertBoth(){
convertDollarsToEuros();
convertEurosToDollars();
}
protected void convertDollarsToEuros() {
double val = Double.parseDouble(dollars.getText().toString());
// in a real app, we'd get this off the 'net
euros.setText(Double.toString(val*0.67));
}
protected void convertEurosToDollars() {
double val = Double.parseDouble(euros.getText().toString());
// in a real app, we'd get this off the 'net
dollars.setText(Double.toString(val/0.67));
}
}
I think what you want is this:
If the user changed the dollar amount, convert it to euro
If the user changed the euro amount, convert it to dollar
If that's the case, you can add a member variable mLastEditedViewId and use a TextWatcher to track which field was last changed. Then, onClick, call convertDollarsToEuros() or convertEurosToDollars accordingly.
In onCreate:
dollars.addTextChangedListener(new MyTextWatcher(dollars));
euros.addTextChangedListener(new MyTextWatcher(euros));
convert.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
switch (mLastEditedViewId) {
case R.id.dollars:
convertDollarsToEuros();
break;
case R.id.euros:
convertEurosToDollars();
break;
}
}
});
Define an inner class for the TextWatcher:
private class MyTextWatcher implements TextWatcher {
private int mTextViewId;
public MyTextWatcher(TextView view) {
mTextViewId = view.getId();
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
mLastEditedViewId = mTextViewId;
}
public void afterTextChanged(Editable s) {
}
}