I'm new to Android (Visual Studio for 20 years). I need to create a clickable control that features 2 lines of text (1 smaller font at the top of the button for a caption and a larger font line for a value - would post an image but I'm not allowed). The size of the larger font scales so that the value will fit on the control.
I'm pretty sure I need to subclass the button control but not sure how to in this case. All samples I have found don't seem to fit the bill.
Have done this easily with VB.Net but I'm stumped when I try with Android. Any help very much appreciated. Might be a handy control for others too.
Thanks
You could try using Spannable in the code like:
public class Test extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button but = (Button) findViewById(R.id.button1);
String butText= "Line 1\nLine 2";
but.setText(formatString(butText));
}
private Spannable formatString(String str) {
int startSpan = str.indexOf("\n");
int endSpan = str.length();
Spannable spanString = null;
spanString = new SpannableString(str);
spanString.setSpan(new TextAppearanceSpan(this,
R.style.custompoint), startSpan, endSpan,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spanString;
}
}
Where you have a style 'custompoint'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style
name="custompoint">
<item name="android:textSize">24sp</item>
<item name="android:textStyle">bold</item>
</style>
</resources>
Related
I want my editText to able to write text in bold, italic and underline along with normal text.
Eg:
The weather is nice today.
I know I can use html tags but I want to perform these operations while writing in the edittext.
What I have tried:
//here textEdits is my model to store the string. As I have multiple editTexts in the activity.
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if(isBold){
String textsequence = textEdits.get(position).getTextString();
if(i > 0){
String sequence = charSequence.subSequence(0, i).toString() +"<b>"+ charSequence.subSequence(i,i+i3).toString() + "</b>";
textEdits.get(position).setTextString(sequence.toString());
editTextcurrrent.setText(Html.fromHtml(sequence.toString()));
editTextcurrrent.setSelection(i+i3);
}
}
}
else {
textEdits.get(position).setTextString(charSequence.toString());
}
}
}
The problem:
The charSequence returns a string without html tags so, once you have set the value, the next time you will get a string without html tags, and therefore you cannot track your previous html edits.
Other than this I have tried Typeface but even that didn't work out.
Also apologies if the work that I tried is not quite understandable, Its a part of a large code so there are quite a lot linked up and I tried to remove as much dependencies as I could.
You will want to use SpannableString:
String yourString = "The weather is nice today."
SpannableString contentSpan = new SpannableString(yourString);
contentSpan.setSpan(new TextAppearanceSpan(activity, R.style.bold_style), weatherFirstPos, weatherLastPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
contentSpan.setSpan(new TextAppearanceSpan(activity, R.style.italic_style), niceFirstPos, niceLastPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
editTextcurrrent.setText(contentSpan, TextView.BufferType.SPANNABLE);
For R.style.bold_style and italic_style you can have something like:
<style name="bold_style">
<item name="android:textStyle">bold</item>
<item name="android:textColor">#color/black</item>
</style>
weatherFirstPos, weatherLastPos, niceFirstPos and niceLastPos are the positions of where you want to apply the style:
int weatherFirstPos = yourString.indexOf("weather");
int weatherLastPos = weatherFirstPos + "weather".length();
Use OnFocusChange Listener & Change EditText properties as you like when EditText gain focus of user
or
you can also set in Xml bold and italic.
<EditText
android:id="#+id/edittext"
android:layout_margin="#dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold|italic"
android:text="enter your name"/>
I am trying to write questions and answers in android studio in the most basic of ways. My plan is to have the answer in white (the color of the background currently)...then when the answer button is hit it'll change the entire thing to black. So how do you have the that Answer span a different color to start?
Button button = (Button) findViewById(R.id.questionButton);
button.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
final String[] Text = {
"Q: Who is the first president of the United States? <COLOR SOMETHING TO MAKE THIS WHITE TEXT-> >A: George Washington</COLOR>"
};
You can use Spannable to achieve this.
String text = "Q: Who is the first president of the United States? <font color='white'>A: George Washington</font>";
textView.setText(Html.fromHtml(text), TextView.BufferType.SPANNABLE);
I'm unable to get SpannableString to work when I set AppTheme to Theme.AppCompat.Light.DarkActionBar.
I have a button and its text is set with a SpannableString. When I use Holo theme the text renders as expected, but when I switch to AppCompat theme the span effects seam to be ignored. How can I get the SpannableString to work using the AppCompat theme?
styles.xml - when switching between those 2 themes I get very different results...
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar" />
<!--<style name="AppTheme" parent="#android:style/Theme.Holo.Light" />-->
</resources>
... for my button that uses SpannableString
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
Button button = (Button) rootView.findViewById(R.id.button);
String detail = "ABC";
String caption = String.format("2 %s", detail);
Spannable span = new SpannableString(caption);
int detailIndex = caption.indexOf(detail);
span.setSpan(new StyleSpan(Typeface.BOLD), 0, detailIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
span.setSpan(new RelativeSizeSpan(0.5f), detailIndex, detailIndex+detail.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
button.setText(span);
return rootView;
}
}
Well, it's not tied to appcompat-v7. If you remove the theme stuff entirely, and just use the default theme, on Android 5.0+ you will get Theme.Material, and the same effect can be seen there.
Part of the Material Design aesthetic is that button captions should be all caps, and however they implemented that is wiping out your spans. appcompat-v7 works with your code on pre-5.0 devices, suggesting that their backported widget effects do not include the app-caps stuff, and that they are delegating to the standard widgets on 5.0+.
Adding android:textAllCaps="false" to your Button in the layout seems to clear up the problem.
I want to set font for the "Video" and "Image" tabs in ActionBarSherlock. I have used the following code to do so. Its showing accurately in ICS but not in the lower version device but I have shown accurate output in the other part of this application by setting TYPE FACE like ...
a.settypeface("ab.tttf");
a.settext("VIDEO");
But how to do I set a TypeFace in the ActionBar in this code:
mTabsAdapter.addTab(bar.newTab().setText("IMAGE"), AFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText("VIDEO"), BFragment.class, null);
Okay . I found it myself some where on SO.
First make an xml file with this in it: tab_title.xml
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/action_custom_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My Custom title"
android:textColor="#fff"
android:textSize="18sp"
android:paddingTop="5dp" />
Then in the class where you in instantiate your ActionBar use this code to set the text on each of the tabs. (This example is using ActionBarSherlock.)
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
String[] tabNames = {"Tab 1","Tab 2","Tab 3"};
for(int i = 0; i<bar.getTabCount(); i++){
LayoutInflater inflater = LayoutInflater.from(this);
View customView = inflater.inflate(R.layout.tab_title, null);
TextView titleTV = (TextView) customView.findViewById(R.id.action_custom_title);
titleTV.setText(tabNames[i]);
//Here you can also add any other styling you want.
bar.getTabAt(i).setCustomView(customView);
}
Try this:
String s = "VIDEO";
SpannableString mSS = new SpannableString(s);
mSS.setSpan(new StyleSpan(Typeface.BOLD), 0, s.length(), 0);
mTabsAdapter.addTab(bar.newTab().setText(mSS),
BFragment.class, null);
To solve this you could create a Special Actionbar class.
Simply create a Class myBar extends Sherlockactionbar and put in the settypeface. If you now create that Bar in your view it will have the Typeface as you whish. For example here is an button with a new Typeface.
public class ChangedButton extends Button{
public ChangedButton(Context context, AttributeSet attrs) {
super(context, attrs);
Typeface font = Typeface.createFromAsset(context.getAssets(), "fonts/viking2.TTF");
this.setTypeface(font);
}
}
regards
First create following custom TypefaceSpan class in your project.Bit changed version of Custom TypefaceSpan to enable to use both .otf and .ttf fonts.
import java.util.StringTokenizer;
import android.content.Context;
import android.graphics.Typeface;
import android.support.v4.util.LruCache;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
public class TypefaceSpan extends MetricAffectingSpan{
/*Cache to save loaded fonts*/
private static LruCache<String, Typeface> typeFaceCache= new LruCache<String, Typeface>(12);
private Typeface mTypeface;
public TypefaceSpan(Context context,String typeFaceName)
{
StringTokenizer tokens=new StringTokenizer(typeFaceName,".");
String fontName=tokens.nextToken();
mTypeface=typeFaceCache.get(fontName);
if(mTypeface==null)
{
mTypeface=Constants.getFont(context, typeFaceName);
//cache the loaded font
typeFaceCache.put(fontName, mTypeface);
}
}
#Override
public void updateMeasureState(TextPaint p) {
p.setTypeface(mTypeface);
}
#Override
public void updateDrawState(TextPaint tp) {
tp.setTypeface(mTypeface);
}
}
Now apply code like this:(I used this on one of my Bangla apps successfully)
SpannableString mstKnwTitle=new SpannableString(getString(R.string.e_mustknow_tab));
SpannableString cntctsTitle=new SpannableString(getString(R.string.e_number_tab));
TypefaceSpan span=new TypefaceSpan(this, "solaimanlipi.ttf");
mstKnwTitle.setSpan(span, 0, mstKnwTitle.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
cntctsTitle.setSpan(span, 0, mstKnwTitle.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Tab tab= actionBar.newTab();
tab.setText(mstKnwTitle);
tab.setTabListener(tabListener);
actionBar.addTab(tab);
tab= actionBar.newTab();
tab.setText(cntctsTitle);
tab.setTabListener(tabListener);
actionBar.addTab(tab);
Original inspiration of my answer was:Styling the Android Action Bar title using a custom typeface
It seems like you are not getting any guidance. I am not sure with my answer's result but yes you can defiantly get idea to make it as you want.
Let me try to help you. I think you have to somewhat play with the in-built default resources of the android sdk.
You have to create custom style:
<style name="MyActionBarTabText" parent="Widget.ActionBar.TabText">
<item name="android:textAppearance">#style/TextAppearance.Holo.Medium</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">12sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textAllCaps">true</item>
<item name="android:ellipsize">marquee</item>
<item name="android:maxLines">2</item>
</style>
<style name="Widget.ActionBar.TabText" parent="Widget">
<item name="android:textAppearance">#style/TextAppearance.Widget.TextView.PopupMenu</item>
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
<item name="android:textSize">18sp</item>
<item name="android:fontFamily">HERE YOU CAN GIVE YOUR FONT</item>
</style>
You can also refer this SO.
Now just apply that theme to your activity and you will get Font of the TabText as you want.
Comment me if have any query.
Enjoy coding... :)
In EXTRA
Another solution could be to modify the tab image to include the text, with GIMP or photoshop something, and then just set those images in the tabs, instead of images and text. It is a bit of an awkward way of doing it but it would work.
Hope this helps!
You can do it with this:
// Set a custom font on all of our ActionBar Tabs
private boolean setCustomFontToActionBarTab(Object root) {
// Found the container, that holds the Tabs. This is the ScrollContainerView to be specific,
// but checking against that class is not possible, since it's part of the hidden API.
// We will check, if root is an instance of HorizontalScrollView instead,
// since ScrollContainerView extends HorizontalScrollView.
if (root instanceof HorizontalScrollView) {
// The Tabs are all wraped in a LinearLayout
root = ((ViewGroup) root).getChildAt(0);
if (root instanceof LinearLayout) {
// Found the Tabs. Now we can set a custom Font to all of them.
for (int i = 0; i < ((ViewGroup) root).getChildCount(); i++) {
LinearLayout child = ((LinearLayout)((ViewGroup) root).getChildAt(i));
TextView actionBarTitle = (TextView) child.getChildAt(0);
Typeface tf = Typeface.createFromAsset(mContext.getAssets(), "font/font.ttf");
actionBarTitle.setTypeface(tf)
}
return true;
}
}
// Search ActionBar and the Tabs. Exclude the content of the app from this search.
else if (root instanceof ViewGroup) {
ViewGroup group = (ViewGroup) root;
if (group.getId() != android.R.id.content) {
// Found a container that isn't the container holding our screen layout.
// The Tabs have to be in here.
for (int i = 0; i < group.getChildCount(); i++) {
if (setCustomFontToActionBarTab(group.getChildAt(i))) {
// Found and done searching the View tree
return true;
}
}
}
}
// Found nothing
return false;
}
Call it with this:
ViewParent root = findViewById(android.R.id.content).getParent();
setCustomFontToActionBarTab(root);
I'm searching for a possibilitie to adjust the text color of the datepicker widget in an android honeycomb app. I knew that the widget inherent the global text-color which is white in my case, but i need a black text-color for the datepicker as the background here is light grey.
Anyone know how to fix this?
DONE IT
Did it in a Theme in the application styles.xml (basically set a style on all EditText fields)
I have this in /values-v11/ so it only affects >HC
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Theme.SelectDate" parent="#android:style/Theme.Holo.NoActionBar">
<item name="android:editTextStyle">#style/Widget.EditText.Black</item>
</style>
<style name="Widget.EditText.Black" parent="#android:style/Widget.EditText">
<item name="android:textColor">#color/black</item>
</style>
</resources>
Then in my AndroidManifest, for the Activity that uses the DatePicker:
<activity
android:name=".ui.phone.SelectDateActivity"
android:label="Date Selection"
android:screenOrientation="portrait"
android:theme="#style/Theme.SelectDate" />
That's it!
My Working Out:
I came to this conclusion by checking the DatePicker source:
https://github.com/android/platform_frameworks_base/blob/master/core/res/res/layout/date_picker.xml
That showed me the DatePicker used NumberPicker
https://github.com/android/platform_frameworks_base/blob/master/core/res/res/layout/number_picker.xml
https://github.com/android/platform_frameworks_base/blob/master/core/res/res/layout/number_picker_with_selector_wheel.xml
The NumberPicker uses an EditText
You can therefore style an EditText
android : how to change the style of edit text?
And if you search in this file for "editText" you will see you can set a style on all edittext fields in one Activity!
https://github.com/android/platform_frameworks_base/blob/master/core/res/res/values/themes.xml
You override this item:
<item name="editTextStyle">#android:style/Widget.EditText</item>
I have found this solution: debugging DatePicker object, I get the object jerarqy. Maybe it's not an elegant solution but it works:
private void setNumberPickerProperties(DatePicker dp)
{
LinearLayout l = (LinearLayout)dp.getChildAt(0);
if(l!=null)
{
l = (LinearLayout)l.getChildAt(0);
if(l!=null)
{
for(int i=0;i<3;i++)
{
NumberPicker np = (NumberPicker)l.getChildAt(i);
if(np!=null)
{
EditText et = (EditText)np.getChildAt(1);
et.setTextColor(Color.BLACK);
}
}
}
}
}
Hi there :) There is an EditText widget somewhere within the datepicker widget. You just have to find it. You can do this by using some creative coding and start searching through the childrens of the datepicker widget using methods like getChildAt(index) and getChildCount() and then loop through it.
You can also do something like this, but i'm not sure that it will work on all devices, better loop through the datepickers children:
DatePicker picker;
ViewGroup childpicker;
childpicker = (ViewGroup) findViewById(Resources.getSystem().getIdentifier("month" /*rest is: day, year*/, "id", "android"));
EditText textview = (EditText) picker.findViewById(Resources.getSystem().getIdentifier("timepicker_input", "id", "android"));
textview.setTextColor(Color.GREEN);
I hope this helps :)
Hmm I did it like this:
private void hackDatePickerTextColorToBlack(){
setTextColorBlack(datePicker);
}
private static void setTextColorBlack(ViewGroup v) {
int count = v.getChildCount();
for (int i = 0; i < count; i++) {
View c = v.getChildAt(i);
if(c instanceof ViewGroup){
setTextColorBlack((ViewGroup) c);
} else
if(c instanceof TextView){
((TextView) c).setTextColor(Color.BLACK);
}
}
}
This changes the text color to black but careful with recursion this could take some time.
Also when the date picker is used the text goes back to white so that sucks!
FYI here's the source for DatePicker: https://github.com/android/platform_frameworks_base/blob/master/core/res/res/layout/date_picker.xml
The EditTexts are NumberPickers
I had a similar issue, although I was looking to change the text size, but that's a minor detail. I used the same process to pick apart the View hierarchy and change the font size. However, once a month (or day or year) was changed, the font changed back to the original value. Great for viewing, bad for editing. I took the next step and added a change listener. Now when the value gets changed, it pops back to the preferred font size:
public void setFontSize(final int size) {
LinearLayout l = (LinearLayout) mPicker.getChildAt(0);
if (l != null) {
l = (LinearLayout) l.getChildAt(0);
if (l != null) {
for (int i = 0; i < 3; i++) {
NumberPicker np = (NumberPicker) l.getChildAt(i);
for (int x = 0; x < np.getChildCount(); x++) {
View view = np.getChildAt(x);
if ((view != null) && (view instanceof TextView)) {
final TextView tv = (TextView) view;
tv.setTextSize(size);
tv.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView v,
int actionId, KeyEvent event) {
tv.setTextSize(size);
return false;
}
});
}
}
}
}
}
}