I want to create a custom Text View and set its text by applying some function to the passed value.
For example if my xml is:-
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="#dimen/margin_raptor_medium"
android:text="someText"/>
then I would want to take the someText; apply my transformation function to it and set the Text again. basically this will be my string Id for which I will fetch the translation from my function.
EDIT:-
so In my custom view class, I am overriding the set Text Method like this:-
#Inject
StringRepository stringRepository
#Override
public void setText(CharSequence text, BufferType type) {
System.out.println("In SetTExt Method");
// modify text here
System.out.println("The text that is set here is:" + text);
String modifiedText = StringRepository.getString((String)text);
super.setText(modifiedText, type);
}
Now the getString Method is giving a Null pointer exception as the map that it accesses is not getting updated.
I am updating this map during Login Time.
Extend TextView class first and then override setText() method, where you can do all the transformations. Thats it.
It should look something like this:
class YouTextView extends TextView {
public YouTextView(Context context) {
super(context);
}
public YouTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public YouTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void setText(CharSequence text, BufferType type) {
// modify text here
super.setText(modifiedText, type);
}
}
Related
I'm using a java class the helps me justify my text ..but the problem is it doesn't appear to treat the HTML tags (they appear as text in my textview) ..how can i modify the behavior of this class? Thanks
JustifiedTextView.java
public class JustifiedTextView extends View {
private void constructor(Context context, AttributeSet attrs) {
mContext=context;
mXmlParser=new XmlToClassAttribHandler(mContext,attrs);
if (attrs!=null){
String text;
int textColor;
int textSize;
int textSizeUnit;
text=mXmlParser.getTextValue();
textColor=mXmlParser.getColorValue();
textSize=mXmlParser.getTextSize();
textSizeUnit=mXmlParser.gettextSizeUnit();
setText(text);
setTextColor(textColor);
if (textSizeUnit==-1)
setTextSize(textSize);
else
setTextSize(textSizeUnit, textSize);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
calculate();
invalidate();
}
public void setText(int resid) {
setText(mContext.getResources().getString(resid));
}
The associated class: XmlToClassAttributeHandler.java
public XmlToClassAttribHandler(Context context,AttributeSet attributeSet){
mContext=context;
mRes=mContext.getResources();
mAttributeSet=attributeSet;
}
public String getTextValue(){
String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT);
if (value==null)
return "";
if (value.length()>1 &&
value.charAt(0)=='#' &&
value.contains("#string/")){
int resId=mRes.getIdentifier(mContext.getPackageName()+":"+value.substring(1), null,null);
value=mRes.getString(resId);
}
return value;
}
This is just nonsense text so that the post would be posted ---Nonsense
This is just nonsense text so that the post would be posted ---Nonsense
This is just nonsense text so that the post would be posted ---Nonsense
Use this
setText(Html.fromHtml(text));
Or this.
trim use to remove extra space while trying to remove the "< p >" tag
setText(Html.fromHtml(text).toString().trim())
i am subclassing TextInputEditText so that i can add a string to a password editText field. here is the subclass:
public class CustomInputEditTextWithPrefix extends TextInputEditText {
public CustomInputEditTextWithPrefix(Context context) {
super(context);
}
public CustomInputEditTextWithPrefix(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomInputEditTextWithPrefix(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public Editable getText() {
Editable s = (Editable) super.getText(); //why is this causing infinite stackoverflow ?
if(s!=null && s.length()>0) {
//salt the password
Editable pwSalt = new SpannableStringBuilder("my secret string");
s= pwSalt.append(s);
}
return s;
}
}
and the imlementation in xml is:
<com.myapp.ui.auth.ui.customviews.CustomInputEditTextWithPrefix
android:id="#+id/password"
android:inputType="textPassword" />
my issue is that when i execute the code the getText() override method keeps getting called over and over again. i took out the inputType but its still being called until stackoverflow. my idea was to append to the front of every string in the TextInputEditText a secret hash. What am i doing wrong ?
Maybe if you skip to assign a new value of s everything will be OK
#Override
public Editable getText() {
Editable s = (Editable) super.getText();
if(s!=null && s.length()>0) {
//salt the password
return new SpannableStringBuilder("my secret string").append(s.toString());
}
return s;
}
i would like to create a class, which extends Button and implement a method, which is alwasy called, when the Button is clicked. But i still want it's OnClickListener to be called.
My Idea is to save the OnClickListener into a private member when the constructor or setOnClickListener is called and then set the OnClickListener to my own OnClickListener. This one would then call my method and the saved OnClickListener.
But i don't see how i can get the OnClickListenr, i only see, how to set it.
Is there a way to acces it?
Or do you have a better idea? (it doesn't matter wheter my method is called before or after the OnClickListener)
I guess you could do this:
public class OnceClickedTwiceRunButton extends Button{
public OnceClickedTwiceRunButton(Context context) {
super(context);
}
public OnceClickedTwiceRunButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public OnceClickedTwiceRunButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private OnClickListener extraClickMethod;
#Override
public void setOnClickListener(OnClickListener newListener)
{
super.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
DefaultClickMethod(v);
if(extraClickMethod != null)
{
extraClickMethod.onClick(v);
}
}
});
extraClickMethod = newListener;
}
private void DefaultClickMethod(View v)
{
//TODO
}
}
I am working on an android app and I have a custom GUI component which extends a TextView.
I want to have my custom control do a task when clicked from my custom control class and my overridden onclick method.
For example my class that extends the TextView implements the OnClick listener and writes a log to the log cat.
Then in my activity, I set an onclick listener to my custom control, and this shows a toast notification.
What I want to happen, is when my custom control is clicked, my activities overridden onclick shows the toast and the custom control class on click method also is run to show the log. But I can only seem to get one working or the other, for example, if I don't run myCustom.setOnClickListener(myListener) then the classes onclick is used and does the log, if I set the onClick listener then I only get the toast not the log.
Below is my custom control class
public class NavTextView extends TextView implements View.OnClickListener
{
public NavTextView(Context context) {
super(context);
setOnClickListener(this);
}
public NavTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setOnClickListener(this);
}
public NavTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOnClickListener(this);
}
public NavTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setOnClickListener(this);
}
#Override
public void onClick(View v) {
Log.d("NavTextView", "This has been clicked");
}
}
Below is my activities onCreate method
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navTextView = (NavTextView)findViewById(R.id.navTextView);
navTextView.setOnClickListener(mClickListener);
}
Hope this makes sense
A View can only have one OnClickListener. In your NavTextView you are setting it there. If you later call setOnClickListener again, you are replacing the previous listener.
What you can do is override setOnClickListener in your custom View, then wrap the OnClickListener and call both.
public class MyTextView extends TextView implements View.OnClickListener
{
OnClickListener _wrappedOnClickListener;
public MyTextView(Context context) {
super(context);
super.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Log.d("NavTextView", "This has been clicked");
if (_wrappedOnClickListener != null)
_wrappedOnClickListener.onClick(view);
}
#Override
public void setOnClickListener(OnClickListener l) {
_wrappedOnClickListener = l;
}
}
Using a simple EditTextPreference in my preferences activity:
<EditTextPreference
android:key="SomeKey"
android:title="#string/some_title"
android:summary="..."
android:numeric="integer"
android:maxLength="2"
/>
Is there a way that this configuration value would be saved as integer? Seems now it just allows to enter numbers, but the value is still saved as string:
Calling:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int value = preferences.getInt("SomeKey", -1);
throws me java.lang.ClassCastException: java.lang.String, and:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String value = preferences.getString("SomeKey", "-1");
retrieves the value successfully.
How to make PreferenceActivity to save value as integer by default?
You could extend EditTextPreference:
public class IntEditTextPreference extends EditTextPreference {
public IntEditTextPreference(Context context) {
super(context);
}
public IntEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public IntEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected String getPersistedString(String defaultReturnValue) {
return String.valueOf(getPersistedInt(-1));
}
#Override
protected boolean persistString(String value) {
return persistInt(Integer.valueOf(value));
}
}
It would be better to overwrite onSetInitialValue() and setText() methods, but then you would have to copy some code from a base class. Above solution is simplier, but it's quite tricky - "string" methods do something with ints. Try to not extend this class further ;-)
You could use it from XML by:
<package.name.IntEditTextPreference
android:key="SomeKey"
android:title="#string/some_title"
android:summary="..."
android:numeric="integer"
android:maxLength="2"
/>
Even if you set android:numeric="integer" it'll be text preference - as its name suggest. You could easily convert string value to int using Integer.valueOf(). Also you could overwrite PreferenceActivity to do conversion automatically on exit.
I think the best solution is to write simple method to get this value from preferences. Something like:
public static int getSomePref(Context context) {
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(context);
String value = prefs.getString("SomeKey", null);
return value == null ? -1 : Integer.valueOf(value);
}
Then you could very easily use it from your code.
Even though an Answer has been parked accepted I would like to share one more shorter way to achieve this :
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int value = Integer.parseInt(preferences.getString("SomeKey", "-1"));
Since you have already set that only numbers can be entered this won't through any exception.
yet to complete my answer :
<EditTextPref
android:key="SomeKey"
android:title="#string/some_title"
android:summary="..."
android:numeric="integer"
android:maxLength="2" />
I know this is an old question with an already accepted answer but I think my solution can be helpful for someone searching for a more complete answer. I have just improved #broot answer a litte and there goes my solution:
Override the EditTextPreference to provide text to int conversion:
public class IntEditTextPreference extends EditTextPreference implements EditTextPreference.OnBindEditTextListener {
private String mText;
public IntEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setOnBindEditTextListener(this);
}
public IntEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOnBindEditTextListener(this);
}
public IntEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setOnBindEditTextListener(this);
}
public IntEditTextPreference(Context context) {
super(context);
setOnBindEditTextListener(this);
}
/**
* Saves the text to the current data storage.
*
* #param text The text to save
*/
public void setText(String text) {
final boolean wasBlocking = shouldDisableDependents();
mText = text;
int value = Integer.parseInt(text);
persistInt(value);
final boolean isBlocking = shouldDisableDependents();
if (isBlocking != wasBlocking) {
notifyDependencyChange(isBlocking);
}
notifyChanged();
}
/**
* Gets the text from the current data storage.
*
* #return The current preference value
*/
public String getText() {
return mText;
}
#Override
protected void onSetInitialValue(Object defaultValue) {
int value;
if (defaultValue != null) {
String strDefaultValue = (String) defaultValue;
int defaultIntValue = Integer.parseInt(strDefaultValue);
value = getPersistedInt(defaultIntValue);
} else {
value = getPersistedInt(0);
}
setText(Integer.toString(value));
}
#Override
public boolean shouldDisableDependents() {
return TextUtils.isEmpty(mText) || super.shouldDisableDependents();
}
#Override
public void onBindEditText(#NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
}
}
In the preferences xml:
<your.package.here.IntEditTextPreference
android:key="some_key"
android:title="#string/some_title"
android:defaultValue="5"
app:useSimpleSummaryProvider="true"/>
Note: Don't use android:numeric nor android:inputType. Since EditTextPreference is not an EditText itself setting those attributes will do nothing. In order to achieve the desired effect on the EditText from the Dialog opened by the EditTextPreference, just set the input type in your custom EditTextPreference by implementing EditTextPreference.OnBindEditTextListener as you can see in the code above.
That's what worked for me.
I had the same Problem. (I wanted SharedPreference to give me a port number that i stored in a preferences xml file as defaultValue).
Implementing all the SharedPreferences methods would be much effort, so writing a custom method in the class that instanced the SharedPreferences, as broot suggested would be best i think.
You can aswell just use the Static method of Integer in the line where you need it:
int number = Integer.valueOf(settings.getString("myNumberString", "0"));
I think this is the shortest one I could come up with:
int CheckInterval = Integer.parseInt(sharedPreferences.getString("check_frequency","60"));