I have a problem with creating custom view. Here is code:
package com.example.App;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
public class v extends View {
public v(Context context) {
super(context);
}
public v(Context context, AttributeSet attrs) {
super(context, attrs);
}
public v(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
I'm trying to use it in layout and getting render error(NullPointerException), here is what IDEA has jenerate in layout code:
<view android:layout_width="wrap_content"
android:layout_height="wrap_content"
class="com.example.App.v" android:id="#+id/view" android:layout_gravity="center"/>
What I'm doing wrong? How to fix it?
Related
Following is my custom TextView Class:
public class MontTextView extends android.support.v7.widget.AppCompatTextView{
public MontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MontTextView(Context context) {
super(context);
init();
}
public void init() {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/Montserrat-Regular.ttf");
setTypeface(tf ,1);
}
}
And in XML I use it like this:
<com.minimalist.gorakh.customviews.MontTextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_20sdp"
android:text="Text"
android:textColor="#fff"
android:textSize="#dimen/_25ssp"
app:layout_constraintBottom_toBottomOf="#+id/betaView"
app:layout_constraintStart_toStartOf="#+id/betaView"
app:layout_constraintTop_toTopOf="#+id/betaView" />
This is working in pre-lollipop(v-19) like this:
And on a marshmallow emulator:
I copied the custom TextView code from a previous project, but couldn't get what am I doing wrong here.
Try this :
import android.widget.*;
import android.util.*;
import android.content.*;
import android.graphics.*;
public class MontTextView extends TextView{
public MontTextView (Context context) {
super(context);
init();
}
public MontTextView (Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MontTextView (Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/Montserrat-Regular.ttf"));
}
}
I extended from LinearLayout and inflated views, but on the screen those views in my layout are not appeared. I see my view group in editor, but it seems like it's empty. No views inside it.
FragmentPickerViewGroup looks like this:
package com.test.pecode.myapplication;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class FragmentPickerViewGroup extends LinearLayout {
private ImageView background;
private Button minusButton;
private Button plusButton;
public FragmentPickerViewGroup(Context context) {
super(context);
init();
}
private void init() {
setOrientation(LinearLayout.HORIZONTAL);
inflate(getContext(), R.layout.view_fragment_picker, this);
minusButton = findViewById(R.id.minus_btn);
plusButton = findViewById(R.id.plus_btn);
background = findViewById(R.id.background_rectangle);
minusButton.setVisibility(INVISIBLE);
minusButton.setGravity(Gravity.TOP | Gravity.START);
minusButton.setBackgroundResource(R.mipmap.button_bg);
background.setBackgroundResource(R.mipmap.rectangle);
background.setBackgroundResource(R.mipmap.rectangle);
plusButton.setBackgroundResource(R.mipmap.button_bg);
plusButton.setGravity(Gravity.TOP | Gravity.END);
}
public FragmentPickerViewGroup(Context context, #Nullable AttributeSet
attrs) {
super(context, attrs);
init();
}
public FragmentPickerViewGroup(Context context, #Nullable AttributeSet
attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public FragmentPickerViewGroup(Context context, AttributeSet attrs, int
defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
}
I used merge tag for my layout. Probably something goes wrong there? This is my layout, which I inflate into my view group:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/minus_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/background_rectangle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:contentDescription="#string/background_rectangle" />
<Button
android:id="#+id/plus_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</merge>
I am trying to create a todo list app. I am adding entered text to the listitems on the enter, it's working fine without the style.
After adding style with paint and drawing its giving null pointer exception. I am initializing all the drawing and paint objects in the init method of "ToDoListItemView". I tried with "log.i" but it's not entering into ToDoListItemView's init method.
Here is my code.
MainActivity:
package todo.prac.com.todolist;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView mylistView=(ListView)findViewById(R.id.myListView);
final EditText editText=(EditText)findViewById(R.id.myEditText);
final ArrayList<String>todoItems=new ArrayList<String>();
final ArrayAdapter<String>adapter;
adapter=new ArrayAdapter<String>(this,R.layout.todolist_view,todoItems);
mylistView.setAdapter(adapter);
editText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if(keyEvent.getAction()==KeyEvent.ACTION_DOWN){
if(i==KeyEvent.KEYCODE_ENTER){
todoItems.add(0,editText.getText().toString());
adapter.notifyDataSetChanged();
editText.setText("");
return true;
}
}
return false;
}
});
}
}
and my ToDoListItemView
package todo.prac.com.todolist;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
public class ToDoListItemView extends TextView {
private Paint marginPaint;
private Paint linePaint;
private int paperColor;
private float margin;
public ToDoListItemView(Context context) {
super(context);
}
public ToDoListItemView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ToDoListItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ToDoListItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private void init(){
Log.i("init","inside");
Resources myResources=getResources();
marginPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint=new Paint(Paint.ANTI_ALIAS_FLAG);
marginPaint.setColor(myResources.getColor(R.color.notepad_margin));
linePaint.setColor(myResources.getColor(R.color.notepad_line));
paperColor=myResources.getColor(R.color.notepad_paper);
margin=myResources.getDimension(R.dimen.notepad_margin);
}
#Override
public void onDraw(Canvas canvas){
canvas.drawColor(paperColor);
if(linePaint==null){
Log.i("linepaint","is null");
}
canvas.drawLine(0,0,getMeasuredHeight(),0,linePaint);
canvas.drawLine(0,getMeasuredHeight(),getMeasuredWidth(),getMeasuredHeight(),linePaint);
canvas.drawLine(margin,0,margin,getMeasuredHeight(),marginPaint);
canvas.save();
canvas.translate(margin,0);
super.onDraw(canvas);
canvas.restore();
}
}
and my TodoList layout xml:
<?xml version="1.0" encoding="utf-8"?>
<todo.prac.com.todolist.ToDoListItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="#color/notepad_text"
android:fadingEdge="vertical"
/>
You are not calling the init() method inside the constructors of your class.
public ToDoListItemView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ToDoListItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ToDoListItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
I solve this problem by this method.
public ToDoListItemView(Context context) {
this(context,null);
}
public ToDoListItemView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public ToDoListItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// initiate your some things
}
Pay attention to: only one super. others in place of this .
I need to set my shape as default background for all of my texts and I don't know how to do this, I want to add many TextView to my project so it's really important for me to do this, I've tried searching the internet but no luck :(
try this code
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;
public class CustomTextView extends TextView{
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomTextView(Context context) {
super(context);
init();
}
public void init() {
if(!isInEditMode()){
setBackgroundResource("Your shape file id ");// like r.drawable.shape_textview
}
}
}
I've written a subclass of EditText. Here is that subclass:
package com.package.foo;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.EditText;
public class FuturaEditText extends EditText{
public FuturaEditText(Context context) {
this(context, null, 0);
}
public FuturaEditText(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FuturaEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if(!isInEditMode()) {
setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/futura.ttf"));
}
}
}
yet it doesn't behave like an EditText, but a TextView. In particular, the soft keyboard isn't rising on focus and it has no EditText formatting. Why?
For completeness - from the source:
public EditText(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.editTextStyle);
}
So, if the constructor is called with no default style, it defaults to editTextStyle
This implementation, with each constructor calling the matched super constructor:
package com.package.foo;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.EditText;
public class FuturaEditText extends EditText{
public FuturaEditText(Context context) {
super(context);
if(!isInEditMode()) {
setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/futura.ttf"));
}
}
public FuturaEditText(Context context, AttributeSet attrs) {
super(context, attrs);
if(!isInEditMode()) {
setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/futura.ttf"));
}
}
public FuturaEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if(!isInEditMode()) {
setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/futura.ttf"));
}
}
}
works. I can only assume that EditText(context, attrs, 0) is not the same as EditText(context, attrs).
You should not invoke the super constructor completing the missing arguments, otherwise there's no way for a client to invoke a constructor with less than 3 arguments (i.e. super.(Context context, AttributeSet attrs)).
The second version is the correct one.