I'm so close to finishing the functions for my app and one thing won't work.
I have an adapter which makes the backgrounds for my views by taking colors I've specified in the color.XML. The function which returns a view with the specified color works excellent.
textView.setBackground works great. However, textView.setText returns "false" in my views and therefore they look like this.
I am trying to get the "android:text" from my TextView in my XML.
What am I missing?
The code:
textView.setBackground(mContext.getResources().getDrawable(mColorID[position]));
textView.setText(mContext.getResources().getString(mThumbIds[position]));
return textView;
}
private Integer[] mColorID = {
R.color.turquoise,R.color.greenSea,
R.color.emerald,R.color.nephritis,
};
private Integer[] mThumbIds = {
R.id.text_test,R.id.text_test,
R.id.text_test,R.id.text_test,
};
EDIT: Added the TextView with the ID I would like to get the text from (text_test).
<TextView
android:id="#+id/text_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!"
</TextView>
You are referencing View ID's and not string resources. Try changing to this:
private Integer[] mThumbIds = {
R.string.text_test,R.string.text_test,
R.string.text_test,R.string.text_test,
mContext.getResources().getString()
returns a localized formatted string from the application's package's
default string table
So if your texts are located in file strings in your array you should have
R.string.text_test,
Related
I have a problem with filling android:entries with String[] from my ViewModel. Code looks like that:
attrs.xml
<declare-styleable name="AutoCompleteDropDown">
<attr name="android:entries" />
</declare-styleable>
My custom dropdown, AutoCompleteDropDown
public class AutoCompleteDropDown extends AppCompatAutoCompleteTextView {
public AutoCompleteDropDown(Context context, AttributeSet attributes) {
super(context, attributes);
TypedArray a = context.getTheme().obtainStyledAttributes(attributes, R.styleable.AutoCompleteDropDown, 0, 0);
CharSequence[] entries = a.getTextArray(R.styleable.AutoCompleteDropDown_android_entries);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<>(context, android.R.layout.simple_dropdown_item_1line, entries);
setAdapter(adapter);
}
...
ViewModel
...
private String[] genders;
public String[] getGenders() {
return genders;
}
public void setGenders(String[] genders) {
this.genders = genders;
}
...
genders are filled in ViewModel constructor:
genders = dataRepository.getGenders();
xml file
<AutoCompleteDropDown
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#={vm.title}"
android:entries="#{vm.genders}"
bind:addTextChangedListener="#{vm.titleValidationChangeListener}"/>
ViewModel is binded correctly, i'm using it many times in that xml file. When i try to run the app i'm getting:
Cannot find the setter for attribute 'android:entries' with parameter
type java.lang.String[] on AutoCompleteDropDown
It works when i use android:entries="#array/genders" but i need this list to be dynamic. Project is in MVVM pattern. Appreciate any help :)
You can use BindingAdapter for this. Like :
#BindingAdapter("entries")
public static void entries(AutoCompleteDropDown view, String[] array) {
view.updateData(array);
}
updateData it's method which you must create in your AutoCompleteDropDown.
And in xml it's using same
app:entries="#{vm.genders}"
<AutoCompleteDropDown
xmlns:customNS="http://schemas.android.com/apk/res/com.example.yourpackage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#={vm.title}"
customNS:entries="#{vm.genders}"
/>
You can check this example Android - custom UI with custom attributes
I am creating a simple Android app. The part I am having trouble is when I am trying to get a String value from the class randomFailureQuotes the method that is important is as follows
public String getQuote(String[] quotes, int indexPosition) {
String quoteToBeDisplayed = new String(quotes[indexPosition]);
return quotes[indexPosition];
}
I try to make this the label of a textView with this code in my EditorActivity class the code for this is as follows.
randomFailureQuotes quote = new randomFailureQuotes();
String Fq = quote.getQuote;
setContentView(R.layout.activity_editor);
TextView quoteDisplay = new TextView(this);
quoteDisplay.setText(Fq);
The error is with when I am trying to set a string value named Fq to the value that the method getQuote returns. The IDE says it can't find the symbol getQuote.
Any help would be greatly appreciated. Feel free to point out any other unrelated errors in my code as I am new at Java and Android development and would love to learn.
EDIT
as requested by RScotCarson here is the rest of my code from both classes
randomFailureQuotes
public class randomFailureQuotes {
List<String> quotes = new ArrayList<>();
double indexPosition = (Math.random() * 4);
protected void onCreate(Bundle savedInstanceState) {
quotes.add("Failure Does't mean the game is over, it means try again with Experience");
quotes.add("Failure is an event not a person. Yesterday ended Last night - Zig Ziglar");
quotes.add("We learn from failure not success");
quotes.add("If you're not prepared to be wrong, you'll never come up with anything original - Ken Robinson");
}
public String getQuote(String[] quotes, int indexPosition) {
String quoteToBeDisplayed = new String(quotes[indexPosition]);
return quotes[indexPosition];
}
}
EditorActivity
package com.example.slick.thegiftoffailure;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;
import java.util.Random;
import static android.R.attr.id;
public class EditorActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//the toolbar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// the quote label
randomFailureQuotes quote = new randomFailureQuotes();
String Fq = quote.getQuote();
setContentView(R.layout.activity_editor);
TextView quoteDisplay = new TextView(this);
quoteDisplay.setText(Fq);
}
}
Let's take a look at your getQuote definition:
public String getQuote(String[] quotes, int indexPosition)
It takes in an array of Strings as well as a position used to index into the array. That means that when you call getQuote it should look more like this...
// quotes is an array declared and instantiated previously
// index is an integer that is also declared and instantiated previously
String Fq = quote.getQuote(quotes, index)
From your question it seems like quote exists in another class. Can you please post the rest of your code from both classes?
If both the index and the array of quotes belong to the RandomFailureQuotes class as member, then you don't need to pass them in to the method as long as they have been instantiated.
EDIT
After the OP provided the extra code, the issue is in the randomFailureQuotes class has a few issues.
onCreate() is NOT a constructor. onCreate is a part of the Android framework and is part of the Activity lifecycle. A standard Java class looks like this...
RandomFailureQuote.java
// It is Java convention to have class names capitalized each word
public class RandomFailureQuotes {
private List<String> quotes = new ArrayList<>();
// The constructor does not need any arguments since you are
// generating the quotes yourself.
public RandomFailureQuotes() {
quotes.add("Failure Does't mean the game is over, it means try again with Experience");
quotes.add("Failure is an event not a person. Yesterday ended Last night - Zig Ziglar");
quotes.add("We learn from failure not success");
quotes.add("If you're not prepared to be wrong, you'll never come up with anything original - Ken Robinson");
}
// Because the index and quotes array are member variables,
// you do not need the arguments in the method definition.
// Also, to get a random number each time you get a quote
// you will need to move the random variable to the method.
// you will need to cast the double value of indexPosition to an int value
public String getQuote() {
double indexPosition = (Math.random() * 4);
String quoteToBeDisplayed = quotes.get((int) indexPosition);
return quoteToBeDisplayed;
}
}
As for the EditorActivity, there are issues there as well. I'm assuming you're not even using the toolbar, so I'm going to remove that from the activity and the activity_layout.xml file.
EditorActivity.java
package com.example.slick.thegiftoffailure;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class EditorActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
// the quote label
randomFailureQuotes quote = new randomFailureQuotes();
String Fq = quote.getQuote();
// You must retrieve the textview from your
// activity_layout.xml file
TextView quoteDisplay = (TextView) findViewById(R.id.text_view);
quoteDisplay.setText(Fq);
}
}
I then modified the xml to only have one TextView that displays a single failure quote. Note that the app will have to be restarted for it to choose a different quote.
activity_editor.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>
Finally, from a developer, I suggest you spend some time learning Java before jumping in to Android. There are intricacies to both that take a little time to learn. There are a million step-y-step tutorials out there on the web to get you started with both. Find one you like and follow it closely! Good luck learning!
You create a new object of type randomFailureQuotes called quote. You didn't pass in parameters for the object and then you tried to access the getQuote data member inside of the newly created object directly. If you want to use the getQuote function you would at least need to include parenthesis so it looks like this: quote.getQuote()
But remember your getQuote function is expecting an array of strings with an index in the array.
getQuote should return a string, which should be fine. It will return the string that is stored at the index value inside of the String array. BUt you need to ensure that you have either passed in the String array and value or defined it in the default constructor.
String Fq = quote.getQuote;
This refers to a member variable (field) called getQuote. It is nowhere defined.
The method getQuote() is unrelated. Variable names and method names occupy distinct namespaces.
I want to change android:hint depending on each model.
(Android device might have different sdcard path. I want to set this value.)
How can I get the element or change the attribute?
Such as
Preferences.java
public class Preferences extends PreferenceActivity {
private void setDeviceSDCardPath () {
String defaultPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
pref = getElementById(R.preferences.pref_id); // <--- invalid, but I want to do like this
pref.hint = "ex.) " + defaultPath; // <-- also invalid
}
}
preferences.xml
<PreferenceCategory android:title="#string/title">
<EditTextPreference
android:id="#+id/pref_id"
android:key="pref_key"
android:title="#string/pref_title"
android:summary="#string/pref_summary"
android:hint="/storage/sdcard"
android:defaultValue="/storage/sdcard/Download/"/>
</PreferenceCategory>
your_editText.setHint("Your New hint");
Check this doc
myTextView.setHint("My conditional hint");
See the javadoc for EditTextPreference:
http://developer.android.com/reference/android/preference/EditTextPreference.html
It is a subclass of DialogPreference and shows the EditText in a
dialog. This EditText can be modified either programmatically via
getEditText(), or through XML by setting any EditText attributes on
the EditTextPreference.
When you got the EditText object by using getEditText() on your EditTextPreference object you can simply use setHint(String message) method. I believe this should work:
EditTextPreference editPref = (EditTextPreference) findPreference(R.id.pref_id);
editPref.getEditText().setHint(message);
yout_editText.setSummary("some description to your preference edit text");
in xml: android:defaultValue or android:summary
I'm passing a listview in to an onselect but theres a couple of ways it's called from different listviews. So i'm trying to work out which listview is being clicked.
I thought I could do the following however the string thats returned is like com.myapp.tool/id/32423423c (type thing) instead of lvAssets.
Here is what I've got:
#Override
public void onNumberRowSelect(ListView listview, clsNameID stat) {
if(listview.getAdapter().toString().equals("lvGenericAssets")){
} else if(listview.getAdapter().toString().equals("lvAssets")){
} else {
Functions.ShowToolTip(getApplicationContext(),
listview.getAdapter().toString());
}
}
As Emil Adz said in first, you can get the id of your list by calling list.getId();
Then use String idList = getResources().getResourceEntryName(id); and you will be able to get the name of the id you have given to your list
Why wont you just use: list.getId(); if you defined it in the XML file then you should define there an id for you ListView.
If you are doing this from code then you can use the list.setId(); to first set it's id.
Another thing you can do is to add a Tag to your listView: list.setTag("list1");
and latter on distinct this listView using the Tag: list.getTag();
When I am using android on websites and reading emails, I notice that I can click on addresses to load into google maps, or click on phone numbers to call, or click on emails and send an email.
These elements on the web are formatted in a variety of ways, so there is some built in function that detects these sort of things.
How do I allow this within my app? I have a page which displays contact information in plain text and I would like the user to just be able to click.
Do I Absolutely need to create clicklisteners for each textview or is there a system function I just need to enable?
Use
android:autoLink="phone"
in textView in the xml layout file
Android has a utility expressly for this purpose: Linkify
TextView noteView = (TextView) findViewById(R.id.noteview);
noteView.setText(someContent);
Linkify.addLinks(noteView, Linkify.ALL);
See also: https://android-developers.googleblog.com/2008/03/linkify-your-text.html
import android.text.util.Linkify;
Linkify.addLinks(text, Linkify.PHONE_NUMBERS);
You can use it in TextView like this,
Set android:autoLink="phone" as below,
<TextView
android:layout_width="fill_parent"
android:id="#+id/text"
android:layout_height="wrap_content"
android:autoLink="phone"
android:gravity="center"
android:linksClickable="true"
android:text="#string/txtCredits" />
However,
For some reason above code does not work all time. So, add below code also,
TextView textView = (TextView) findViewById(R.id.text);
textView.setMovementMethod(LinkMovementMethod.getInstance());
android:autoLink="phone"
was working for me on all phones... except Samsung.
Therefore, I chose the following option. Transformed phone number texts to support click to call:
+49 / 30 123456789
and then used this static helper method to add web link support to my TextViews
public static void linkifyTextViews(#NonNull TextView... textViews) {
for (TextView textView : textViews) {
Linkify.addLinks(textView, Linkify.WEB_URLS);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
If you want to detect different patterns like emails, contact numbers, weblink and set a separate on click implementations for these patterns I suggest you to use CustomClickableEmailPhoneTextview
Sample Code to use the library.
CustomPartialyClickableTextview customPartialyClickableTextview= (CustomPartialyClickableTextview) findViewById(R.id.textViewCustom);
/**
* Create Objects For Click Patterns
*/
ClickPattern email=new ClickPattern();
ClickPattern phone=new ClickPattern();
ClickPattern weblink=new ClickPattern();
/**
* set Functionality for what will happen on click of that pattern
* In this example pattern is email
*/
email.setOnClickListener(new ClickPattern.OnClickListener() {
#Override
public void onClick() {
Toast.makeText(MainActivity.this,"email clicked",Toast.LENGTH_LONG).show();
}
});
/**
* set Functionality for what will happen on click of that pattern
* In this example pattern is phone
*/
phone.setOnClickListener(new ClickPattern.OnClickListener() {
#Override
public void onClick() {
Toast.makeText(MainActivity.this,"phone clicked",Toast.LENGTH_LONG).show();
}
});
/**
* set Functionality for what will happen on click of that pattern
* In this example pattern is weblink
*/
weblink.setOnClickListener(new ClickPattern.OnClickListener() {
#Override
public void onClick() {
Toast.makeText(MainActivity.this,"website clicked",Toast.LENGTH_LONG).show();
}
});
/**
* set respective regex string to be used to identify patter
*/
email.setRegex("\\b[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,4}\\b"); // regex for email
phone.setRegex("[1-9][0-9]{9,14}"); // regex for phone number
weblink.setRegex("^(https?|ftp|file)://[-a-zA-Z0-9+&##/%?=~_|!:,.;]*[-a-zA-Z0-9+&##/%=~_|]"); // regex for weblink
/**
* add click pattern to the custom textview - first parameter is tag for reference second parameter is ClickPattern object
*/
customPartialyClickableTextview.addClickPattern("email",email);
customPartialyClickableTextview.addClickPattern("phone",phone);
customPartialyClickableTextview.addClickPattern("weblink",weblink);