Custom TextView cuts off using wrap_content - java

I created a custom TextView, in order to add a new font:
public class CustomTextView extends TextView{
public CustomTextView(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
setTypeface(SplashActivity.SECRET_CODE_TYPEFACE, Typeface.NORMAL);
}
public CustomTextView(Context context, AttributeSet attrs){
super(context, attrs);
setTypeface(SplashActivity.SECRET_CODE_TYPEFACE, Typeface.NORMAL);
}
public CustomTextView(Context context){
super(context);
setTypeface(SplashActivity.SECRET_CODE_TYPEFACE, Typeface.NORMAL);
}
}
Now, when I use this TextView, the text is cut off:
And here is my XML:
<com.whereisthemonkey.sqlsheetmanager.Graphics.CustomTextView
android:layout_width="match_parent"
android:text="#string/title"
android:textSize="56sp"
android:layout_height="wrap_content"
android:gravity="center" />

android:padding="10dp"
Add padding into your text view,as shown below:
<com.whereisthemonkey.sqlsheetmanager.Graphics.CustomTextView
android:layout_width="match_parent"
android:text="#string/title"
android:textSize="56sp"
android:padding="10dp"
android:layout_height="wrap_content"
android:gravity="center" />

Related

My Toolbar compound view doesn't align with parent view group properly

I am in need of a custom toolbar for a new app that I am writing. When I try to add the view to my main layout it doesn't align properly. Can someone please explain why?
public class LjCustomToolbar extends Toolbar {
private Context context;
private LayoutInflater layoutInflater;
private TextView toolbar_title;
public LjCustomToolbar(Context context) {
super(context);
initialize(context);
}
public LjCustomToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
public LjCustomToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context);
}
private void initialize(Context context) {
this.context = context;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.layout.custom_toolbar, this);
}
}
custom_toolbar.xml
<Toolbar
style="#style/LjToolBarDefault"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Profile"
style="#style/LjBodyNormalText"
android:textColor="#color/white"
android:layout_gravity="center"
android:id="#+id/toolbar_title_text" />
</Toolbar>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:background="#color/lj_color_primary">
<us.lj.CustomViews.LjCustomToolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
Click here to see my current layout
Can you show a screenshot, to see what is not working.
Why do you want to customize the Toolbar? If you want to add another views inside the toolbar you can do it in xml as all other UI elements

Custom font for clock textview

I am new in world of android developement and I want to make a clock such that each digit of time has it's own typeface.
Hour digits has it's own typeface and minutes digit has its own typeface.
How can i do this. Help me.
Let's say your font name is DemoFont . Make a Class which extends TextView. And initialize the font for the DemoFont .
Next place the .ttf file of that font in the assets folder.
public class DemoFont extends TextView {
public DemoFont (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public DemoFont (Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DemoFont (Context context) {
super(context);
init();
}
private void init() {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"demofont.ttf");
setTypeface(tf);
}
}
Now, In your layout file you can use this like this way.
<YOUR_PACKAGE_NAME.DemoFont
android:layout_width="match_parent"
android:layout_height="wrap_content" />
First, you need to download a font file, which is usually of the .otf format. Then, you need to import this font into your assets folder in your android studio or eclipse project. After doing this you can create a new Typeface and set it to your text view. In terms of having different fonts for the hours and minutes digit, you need to create a layout with multiple text views. For example, you could do something like the following
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/hours_digit"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=": "
android:id="#+id/time_colon"
android:layout_toEndOf="#id/hours_digit" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/time_colon"
android:id="#+id/minutes_digit"/>
</RelativeLayout>
Another way to accomplish this, rather than setting a typeface to a textview every single time, is to create your own custom textview, so that the typeface will be applied whenever you're using it. For example, for the minutes text view, you could do:
public class MinutesTextView extends TextView {
// Constructor method for the text view...
public MinutesTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
// Constructor method for the text view...
public MinutesTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
// Constructor method for the text view...
public MinutesTextView(Context context) {
super(context);
init(null);
}
// Initializes any UI properties of the text view.
private void init(AttributeSet attrs) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "Minutes-font-file.otf");
setTypeface(myTypeface);
}
}
and the, using the layout file from earlier.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.yourpackage.MinutesTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/hours_digit"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=": "
android:id="#+id/time_colon"
android:layout_toEndOf="#id/hours_digit" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/time_colon"
android:id="#+id/minutes_digit"/>
</RelativeLayout>
First copy the fonts to the assets folder in your project.
For Hour Textview
public class HourTextView extends TextView {
public HourTextView(Context context) {
super(context);
init(null);
}
public HourTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
public HourTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
public HourTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
// Initializes any UI properties of the text view.
private void init(AttributeSet attrs) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "Hour-font-file.otf");
setTypeface(myTypeface);
}
}
For Minute Textview
public class MinuteTextView extends TextView {
public MinuteTextView(Context context) {
super(context);
init(null);
}
public MinuteTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
public MinuteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
public MinuteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
// Initializes any UI properties of the text view.
private void init(AttributeSet attrs) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "Minute-font-file.otf");
setTypeface(myTypeface);
}
}
For Seconds Textview
public class SecondTextView extends TextView {
public SecondTextView(Context context) {
super(context);
init(null);
}
public SecondTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
public SecondTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
public SecondTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
// Initializes any UI properties of the text view.
private void init(AttributeSet attrs) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "Second-font-file.otf");
setTypeface(myTypeface);
}
}
and in xml file do this,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<com.yourpackage.HourTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="10"
android:id="#+id/hourText" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text=" : " />
<com.yourpackage.MinuteTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="45 "
android:id="#+id/minuteText" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text=" : " />
<com.yourpackage.SecondTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="28"
android:id="#+id/secondsText" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
public TextView textView;
int countInt;
private int mInterval = 1000; // 1 second by default, can be changed later
private Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
mHandler = new Handler();
startRepeatingTask();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
countInt=countInt+1;
textView.setText(String.valueOf(countInt));
} finally {
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
}

Cant use OnClickListener in Custom Layout in Android?

So I made my own LinearLayout because I needed a horizontal number picker. I am using this custom layout twice in my activity:
XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/button_minus"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="#string/lt"
android:textSize="30sp"
android:textStyle="bold" />
<EditText
android:id="#+id/number"
android:layout_width="75dp"
android:layout_height="match_parent"
android:inputType="number"
android:gravity="center"
android:focusable="false"
android:text="0" />
<Button
android:id="#+id/button_plus"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="#string/gt"
android:textSize="30sp"
android:textStyle="bold" />
</LinearLayout>
JAVA:
public class NumberPickerHorizontal extends LinearLayout
{
private final EditText number;
private final Button button_minus, button_plus;
public NumberPickerHorizontal(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.numberpicker_horizontal, this, true);
number = (EditText) findViewById(R.id.number);
button_minus = (Button) findViewById(R.id.button_minus);
button_minus.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int count = Integer.parseInt(number.getText().toString());
number.setText(count--);
}
});
button_plus = (Button) findViewById(R.id.button_plus);
button_plus.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int count = Integer.parseInt(number.getText().toString());
number.setText(count++);
}
});
}
}
You'll notice I'm trying to activate the onClick methods for the plus and minus buttons... However, when I actually click the buttons, I get the following error:
android.content.res.Resources$NotFoundException: String resource ID #0x0
Not quite sure what I'm doing wrong.
You are trying to setText for 0, which should be an string resource(int).
Also your new increased value is never used. Increase count before setting the text. Then use setText(String.valueOf(increased count value)).
You should do this:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="#+id/button_minus"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="#string/lt"
android:textSize="30sp"
android:textStyle="bold" />
<EditText
android:id="#+id/number"
android:layout_width="75dp"
android:layout_height="match_parent"
android:inputType="number"
android:gravity="center"
android:focusable="false"
android:text="0" />
<Button
android:id="#+id/button_plus"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="#string/gt"
android:textSize="30sp"
android:textStyle="bold" />
</merge>
Java:
public class NumberPickerHorizontal extends LinearLayout
{
private final EditText number;
private final Button button_minus, button_plus;
#Override
public NumberPickerHorizontal(Context context) {
super(context);
init(context);
}
#Override
public NumberPickerHorizontal(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init(context);
}
#TargetApi(11)
#Override
public NumberPickerHorizontal(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
#TargetApi(21)
#Override
public NumberPickerHorizontal(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
//android:layout_width="match_parent"
//android:layout_height="wrap_content"
//set these where you instantiate the view, XML or code!
this.setOrientation(LinearLayout.HORIZONTAL);
LayoutInflater.from(context).inflate(R.layout.numberpicker_horizontal, this, true);
number = (EditText) findViewById(R.id.number);
button_minus = (Button) findViewById(R.id.button_minus);
button_minus.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int count = Integer.parseInt(number.getText().toString());
count--;
number.setText(String.valueOf(count));
}
});
button_plus = (Button) findViewById(R.id.button_plus);
button_plus.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int count = Integer.parseInt(number.getText().toString());
count++;
number.setText(String.valueOf(count));
}
});
}
So the changes were:
1.) added <merge> to remove the duplicate layout
2.) added the remaining 3 constructors for the view in case the framework calls them
3.) added String.valueOf() around your int so that it's not perceived as a resource identifier by setText().
Try this:
View v = LayoutInflater.from(context).inflate(R.layout.numberpicker_horizontal, this, true);
And replace all findViewById by v.findViewById

Best way to achieve grid RecyclerView, where items are square images with some text below it

I'm developing a music store where we show the albums in a grid. Each item is comprised of a cover album (which is a square image) and some text below it which shows artist name, album name, etc. This is the approximate result that I want:
Cover images are not uni-sized, some are 1000x1000, some are 500x500, and maybe there'll be some other sizes.
This is the current xml layout that I use for each item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/cover"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/artistName"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Here is the important part of the RecyclerView's Adapter, the rest is typical stuff:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.artistName.setText(mAlbums.get(position).name);
Picasso.with(holder.cover.getContext())
.load(mAlbums.get(position).primaryImage)
.into(holder.cover);
}
I get this result:
The right picture is 500x500 and the other two are 1000x1000
However if I add some resize to the images
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.artistName.setText(mAlbums.get(position).name);
Picasso.with(holder.cover.getContext())
.load(mAlbums.get(position).primaryImage)
.resize(300, 300)
.centerInside()
.into(holder.cover);
}
I'll get a better result like:
300 is just a random number. I can replace it with SCREEN_WIDTH/3.
So.... Is there a better approach to tackle this problem (which I think is a very general problem in apps)?
use the following SquareRelativeLayout
package net.simplyadvanced.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
/** A RelativeLayout that will always be square -- same width and height,
* where the height is based off the width. */
public class SquareRelativeLayout extends RelativeLayout {
public SquareRelativeLayout(Context context) {
super(context);
}
public SquareRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(VERSION_CODES.LOLLIPOP)
public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Set a square layout.
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
look at the answer
Recyclerview - GridLayoutManager: Set square dimensions
you can do like this. on your activity/fragment.
private void setRecyclerView() {
productRecyclerView.setHasFixedSize(true);
final GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
productRecyclerView.setLayoutManager(layoutManager);
recyclerViewAdapter = new ProductListAdapter(getActivity());
productRecyclerView.setAdapter(recyclerViewAdapter);
}
or you can achieve by adding different viewholders of different row/column heights.
Use a fixed height for item xml Like
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="100dp">
<ImageView
android:id="#+id/cover"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/artistName"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Hope this will solve the problem

Android scrollview remove blue light

When you scroll on Android using scrollview, it generates a blue light the direction you are scrolling in. How would I remove the blue light?
My manifest:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sobreScrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#android:color/transparent"
android:scrollingCache="false"
android:fadingEdge="none"
android:fadingEdgeLength="0dp"
android:scrollbars="none"
android:scrollbarStyle="insideOverlay"
>
<LinearLayout
android:id="#+id/contentSobre"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
Java source code:
package com.my.app.section;
import android.content.Context;
import android.util.AttributeSet;
import com.my.app.BaseSection;
import com.my.app.R;
public class SobreSection extends BaseSection {
public SobreSection(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SobreSection(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SobreSection(Context context) {
super(context);
}
#Override
protected void onFinishInflate() {
// TODO Auto-generated method stub
super.onFinishInflate();
findViewById(R.id.sobreScrollView).setVerticalFadingEdgeEnabled(false);
findViewById(R.id.sobreScrollView).setVerticalScrollBarEnabled(false);
}
}
Try adding this to your ScrollView in your layout.xml:
android:overScrollMode="never"
or add this to your code:
findViewById(R.id.sobreScrollView).setOverScrollMode(ScrollView.OVER_SCROLL_NEV‌​ER);
Add this extra line to your ScrollView definition:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sobreScrollView"
...
android:overScrollMode="never">

Categories