For my Android application I have implemented a ListView that is populated by a Custom Adapter from BaseAdapter and a custom Layout for the rows.
Now i would like to make entries checkable by using the corresponding methods from ListView, like setItemChecked() or getCheckedItemCount().
I created a custom Layout class for the row layout that imlpements Checkable interface and retrieved the Button using findViewById to be able to access it inside the overridden methods from Checkable.
When long clicking on an entry in the list, the methods get invoked, but I get a NullpointerException, saying the CheckBox is referencing null:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.CompoundButton.setChecked(boolean)' on a null object reference
What is the appropriate way to link the checkbox of each entry inside a checkable Layout?
The checkable Layout class looks like this:
package com.lastname.name.arcadaobjecttracker;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Checkable;
import android.widget.LinearLayout;
//extend the Layout for the row view (each element in the listView) to add support for checkable rows (called by the listView methods like setItemChecked() etc.)
public class CheckableRowLayout extends LinearLayout implements Checkable
{
View view;
CheckBox checkBox;
public CheckableRowLayout(Context context)
{
super(context);
init(context);
}
public CheckableRowLayout(Context context, #Nullable AttributeSet attrs)
{
super(context, attrs);
init(context);
}
public CheckableRowLayout(Context context, #Nullable AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context)
{
checkBox = (CheckBox) findViewById(R.id.checkBox);
}
#Override
public void setChecked(boolean checked)
{
checkBox.setChecked(checked);
}
#Override
public boolean isChecked()
{
return checkBox.isChecked();
}
#Override
public void toggle()
{
checkBox.toggle();
}
}
The Layout consists of the following xml file with checkbox:
<?xml version="1.0" encoding="utf-8"?>
<com.lastname.name.arcadaobjecttracker.CheckableRowLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:visibility="visible" />
<include
layout="#layout/list_view_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.lastname.name.arcadaobjecttracker.CheckableRowLayout>
which includes the rest of the layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/thumbnailImageView"
android:layout_width="80dp"
android:layout_height="45dp"
android:layout_marginBottom="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_videocam_black_24dp" />
<TextView
android:id="#+id/nameTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:singleLine="true"
android:text="Thisisaverylongnameforavideofilethatforsureexceedsthetextviewsize"
android:textColor="#color/black"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/thumbnailImageView"
app:layout_constraintTop_toTopOf="#+id/thumbnailImageView" />
<TextView
android:id="#+id/dateTextView"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:singleLine="true"
android:text="2018-01-01"
app:layout_constraintBottom_toBottomOf="#+id/thumbnailImageView"
app:layout_constraintStart_toEndOf="#+id/thumbnailImageView" />
<TextView
android:id="#+id/durationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:singleLine="true"
android:text="Duration"
android:textAlignment="textStart"
app:layout_constraintBottom_toBottomOf="#+id/dateTextView"
app:layout_constraintStart_toEndOf="#+id/dateTextView" />
<TextView
android:id="#+id/hasTrackingTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="TextView"
android:textAlignment="viewEnd"
app:layout_constraintBottom_toBottomOf="#+id/durationTextView"
app:layout_constraintEnd_toEndOf="parent" />
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="20dp" />
<android.support.constraint.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.42" />
</android.support.constraint.ConstraintLayout>
Related
How can a menu be made with this logic? what is logic? I used ExpandableListview this time, it made all of them as drop-down menus, I tried with recycler, and I couldn't make the drop-down menu part of it. what should i use?
you need create a custom-compound view and use animation for fadein/fadeout or dropDown/dropUp effect here is my sample code you can optimize it as you need:
Result:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.junk3.Menu
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</com.example.junk3.Menu>
</androidx.constraintlayout.widget.ConstraintLayout>
drop_down_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000">
<LinearLayout
android:id="#+id/box_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="#+id/item_1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#FF0000"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="item_1 (click me)"
android:textColor="#000000" />
</LinearLayout>
<LinearLayout
android:id="#+id/item_1_detail"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="1dp"
android:background="#FFFFFF"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/item_1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="item_1_1"
android:textColor="#000000" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="item_1_2"
android:textColor="#000000" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="item_1_3"
android:textColor="#000000" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/box_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/box_1">
<LinearLayout
android:id="#+id/item_2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#FF0000"
android:orientation="horizontal">
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="item_2 (click me)"
android:textColor="#000000" />
</LinearLayout>
<LinearLayout
android:id="#+id/item_2_detail"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#FFFFFF"
android:orientation="horizontal">
<TextView
android:id="#+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="item_2_1"
android:textColor="#000000" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</merge>
MainActivity.java:
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import com.example.junk3.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var text:TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Menu.java :
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class Menu extends LinearLayout {
private Context ctx;
private LinearLayout item_1,item_2,item_1_detail,item_2_detail;
public Menu(Context context, AttributeSet attrs) {
super(context, attrs);
ctx = context;
initView(ctx);
}
public Menu(Context context) {
this(context, null);
ctx = context;
initView(ctx);
}
public Menu(Context context, AttributeSet attrs,int defSyle){
super(context,attrs,defSyle);
ctx = context;
initView(ctx);
}
public void initView(Context context){
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.drop_down_menu,this);
}
#Override
public void onFinishInflate() {
super.onFinishInflate();
item_1 = (LinearLayout) findViewById(R.id.item_1);
item_2 = (LinearLayout) findViewById(R.id.item_2);
item_1_detail = (LinearLayout) findViewById(R.id.item_1_detail);
item_2_detail = (LinearLayout) findViewById(R.id.item_2_detail);
item_1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(item_1_detail.getLayoutParams().height>0){
Log.e("detail_1","1");
slideView(item_1_detail, item_1_detail.getLayoutParams().height, 0);
}else{
slideView(item_1_detail, 0, dp2px(ctx.getResources(),120));
}
}
});
item_2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(item_2_detail.getLayoutParams().height>0){
slideView(item_2_detail, item_2_detail.getLayoutParams().height, 0);
}else{
slideView(item_2_detail, 0, dp2px(ctx.getResources(),40));
}
}
});
}
public static void slideView(View view, int currentHeight, int newHeight) {
Log.e("here3","ddd");
ValueAnimator slideAnimator = ValueAnimator
.ofInt(currentHeight, newHeight)
.setDuration(500);
/* We use an update listener which listens to each tick
* and manually updates the height of the view */
slideAnimator.addUpdateListener(animation1 -> {
Integer value = (Integer) animation1.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
});
/* We use an animationSet to play the animation */
AnimatorSet animationSet = new AnimatorSet();
animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.play(slideAnimator);
animationSet.start();
}
public static int dp2px(Resources resource, int dp) {
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,resource.getDisplayMetrics()
);
}
}
I have a CustomView which contains a LinearLayout that holds an EditText & another custom view element. However, when I run my app and touch the EditText it does not behave as expected (doesn't appear to receive focus & the soft keyboard doesn't open). I've tried setting duplicateParentState="true" on both the EditText & the LinearLayout. I also attached an onTouchEventListener to the EditText that calls a simple toast & the toast did show up.
Here's the code for my CustomView.
form_field.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_marginBottom="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/grey_rounded_borders">
<EditText
android:id="#+id/edit_text"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:inputType="text"
android:padding="10dp"
android:textColor="#2d6169"
android:textSize="18sp"
android:background="#color/transparent" />
<RelativeLayout
android:layout_marginStart="5dp"
android:layout_marginEnd="10dp"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<com.example.app.ValidationIcon
android:id="#+id/validation_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
tools:ignore="ContentDescription" />
</RelativeLayout>
</LinearLayout>
FormField.java
package com.example.app;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import java.util.ArrayList;
public class FormField extends LinearLayout {
private EditText editText;
private ValidationIcon validationIcon;
private Integer fieldInputType;
private String fieldInputHint;
public FormField(Context context)
{
super(context);
}
public FormField(Context context, AttributeSet attributeSet)
{
super(context, attributeSet);
TypedArray attrs = context.obtainStyledAttributes(attributeSet, R.styleable.FormField, 0, 0);
fieldInputType = attrs.getInt(
R.styleable.FormField_fieldInputType,
InputType.TYPE_TEXT_VARIATION_NORMAL
);
fieldInputHint = attrs.getString(
R.styleable.FormField_fieldInputHint
);
attrs.recycle();
inflate(getContext(), R.layout.form_field, this);
this.setFocusable(true);
this.setFocusableInTouchMode(true);
editText = (EditText)findViewById(R.id.edit_text);
editText.setInputType(fieldInputType);
editText.setHint(fieldInputHint);
editText.setFocusableInTouchMode(true);
validationIcon = (ValidationIcon)findViewById(R.id.validation_icon);
validationIcon.setValid(true);
ArrayList<View> touchables = new ArrayList<View>();
touchables.add(this);
touchables.add(editText);
addTouchables(touchables);
}
public FormField(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
}
registration_layout.xml
<RelativeLayout android:id="#+id/container"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp">
<RelativeLayout android:id="#+id/account_details"
android:layout_marginBottom="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.example.app.FormField
android:id="#+id/name_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:fieldInputHint="#string/name_field_hint" />
<com.example.app.FormField
android:id="#+id/email_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:fieldInputHint="#string/email_field_hint" />
<com.example.app.FormField
android:id="#+id/password_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:fieldInputHint="#string/password_field_hint" />
<com.example.app.FormField
android:id="#+id/re_password_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:fieldInputHint="#string/re_password_field_hint" />
</RelativeLayout>
</RelativeLayout>
Min SDK Version is set at 14, target is set at 20. Any help would be greatly appreciated!
EDIT:
I got this logcat message today while testing long presses on my FormFields.
W/TextView﹕ TextView does not support text selection. Action mode cancelled.
I double checked my code and the EditText element is only ever cast as an EditText. If the EditText is being cast to a TextView that would explain my original issues but now I'm confused as to why or how it was cast as a TextView.
It looks like you are extending LinearLayout but never using it in your layout. From what you've posted, you aren't using the FormField at all and the only custom View I see is the ValidationIcon view. So hooking the touch events into EditText and ValidationIcon aren't occurring because you aren't using FormField in your layout.xml.
Rather than extending LinearLayout, why not just use the predefined methods and attributes to handle the behaviour you are trying to achieve. For example, displaying keyboard, requesting focus, and displaying hint:
<EditText
android:id="#+id/edit_text"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
**android:inputType="text"**
**android:hint="#styleable/FormField_fieldInputHint"**
android:padding="10dp"
android:textColor="#2d6169"
android:textSize="18sp"
android:background="#color/transparent" />
The keyboard should display when the edit text receives focus, if not you could programmatically do this by requesting focus and handling the IME manager call. For example, from the Activity/Fragment:
//call this from onViewCreated to grab focus and begin the flow
editText.requestFocus();
//set focus listener to handle keyboard display
editText.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
} else {
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.showSoftInputFromWindow(myEditText.getWindowToken(), 0);
}
});
Make sure have not been setting inputType:'none' or '0X000000'
use this code for custom Edittext with title
custom_view.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:foregroundGravity="right"
app:layout_anchorGravity="right">
<LinearLayout
android:orientation="vertical"
android:id="#+id/search_closed_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center|right"
android:background="#color/white"
android:foregroundGravity="center"
android:gravity="right">
<TextView
android:id="#+id/txt_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|left"
android:layout_marginStart="16dp"
android:layout_marginTop="14dp"
android:fontFamily="#font/intel"
android:foregroundGravity="center"
android:text="textview"
android:textColor="#color/title_color"
android:textSize="14dp"
android:textStyle="bold" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/lay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:clickable="true"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/edt_text"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/edit_txtbg"
android:fontFamily="#font/intel"
android:gravity="center|start"
android:paddingStart="24dp"
android:textColor="#color/text_color"
android:textColorHint="#color/txt_hint"
android:textSize="#dimen/text_nev"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/img_add_patient"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</FrameLayout>
CustomEditText.kt
package com.mdppractice.custom
import android.content.Context
import android.text.InputType
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.TextView
import com.mdppractice.R
class CustomEditText(
context: Context,
attrs: AttributeSet,
) : FrameLayout(context, attrs) {
private var txt_title: TextView
private var edt_text: EditText
init {
LayoutInflater.from(context)
.inflate(R.layout.custom_view, this, true)
txt_title = findViewById(R.id.txt_title)
edt_text = findViewById(R.id.edt_text)
val a = context.obtainStyledAttributes(attrs, R.styleable.CustomEditText)
txt_title.text = a.getString(R.styleable.CustomEditText_title)
edt_text.hint = a.getString(R.styleable.CustomEditText_hint)
when(a.getString(R.styleable.CustomEditText_inputType)) {
"number" -> edt_text.inputType = InputType.TYPE_CLASS_PHONE
"textCapSentences" -> edt_text.inputType = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
"text" -> edt_text.inputType = InputType.TYPE_CLASS_TEXT
}
a.recycle()
}
fun setmInputType(type: Int) {
edt_text.setRawInputType(InputType.TYPE_CLASS_TEXT)
setmInputType(type)
}
fun setTitle(title: Int) {
txt_title.setText(title)
}
fun set_Text(title: Int) {
edt_text.setText(title)
}
fun getTitle(): String {
return txt_title.text.toString()
}
fun get_Text(): String {
return edt_text.text.toString()
}
}
main/../attr.xml
<declare-styleable name="CustomEditText">
<attr name="title" format="string"/>
<attr name="onCenter" format="boolean"/>
<attr name="hint" format="string"/>
<attr name="maxLength" format="integer"/>
<attr name="inputType" format="string"/>
</declare-styleable>
#drawable/edit_txtbg
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="#+id/listview_background_shape">
<stroke android:width="1dp" android:color="#color/button_bg_border" />
<padding android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp" />
<corners android:radius="6dp"/>
<solid android:color="#color/button_bg" />
</shape>
use in layout
<com.mdppractice.custom.CustomEditText
android:id="#+id/edt_custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="Patient ID/Phone"
android:autofillHints="#string/verified"
android:foregroundGravity="center"
android:hint="Please enter name"
app:inputType="textCapSentences"
android:textColor="#color/title_color"
android:textSize="14dp"
android:textStyle="bold" />
thanks you
Good day guys, I wonder why when i drag the widget out to my home screen, it only display "widget failed to load" instead of my widget layout. I need help.
Widget.java
package com.fyp.atms;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import android.widget.Toast;
public class Widget extends AppWidgetProvider{
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
#Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onDeleted(context, appWidgetIds);
Toast.makeText(context, "Widget deleted!", Toast.LENGTH_SHORT).show();
}
}
widget.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Spinner
android:id="#+id/spinner1"
android:layout_width="114dp"
android:layout_height="40dp" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<TableLayout
android:layout_width="130dp"
android:layout_height="80dp">
<EditText
android:id="#+id/wid_ToTranslate"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
<Spinner
android:id="#+id/spinner2"
android:layout_width="114dp"
android:layout_height="40dp" />
</TableLayout>
<Button
android:id="#+id/wid_trans"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_weight="50"
android:text="Translate" />
</LinearLayout>
<TextView
android:id="#+id/wid_Translated"
android:layout_width="130dp"
android:layout_height="35dp"
android:ems="10" />
</LinearLayout>
mywidget.xml (AppWidgetProvider)
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="274dp"
android:minHeight="200dp"
android:initialLayout="#layout/widget"
android:updatePeriodMillis="1800000">
</appwidget-provider>
You can't use a Spinner or an EditText in a Widget. That's because every Widget layout must be based on RemoteViews. Following every layout that is supported:
Layout classes
FrameLayout
LinearLayout
RelativeLayout
GridLayout
Widget classes
AnalogClock
Button
Chronometer
ImageButton
ImageView
ProgressBar
TextView
ViewFlipper
ListView
GridView
StackView
AdapterViewFlipper
Read more about it in the Docs.
The problem is your layout contains an EditText which is not supported by widgets on Android.
For a complete list of views you may use see: http://developer.android.com/guide/topics/appwidgets/
I extended class View to create a custom view (at the moment the class might not make any practical sense - please ignore it ;>):
package com.example.splittheisland;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class BoardView extends View {
private Paint mPaintGrid = new Paint();
private Paint mPaintContour = new Paint();
public BoardView(Context c) {
super(c);
init();
}
public BoardView(Context c, AttributeSet attrs) {
super(c, attrs);
init();
}
public BoardView(Context c, AttributeSet attrs, int defStyles) {
this(c, attrs);
init();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(100,100,200,200+counter*100,mPaintContour);
}
private void init() {
mPaintGrid.setColor(Color.BLACK);
mPaintGrid.setStrokeWidth(2);
mPaintContour.setColor(Color.BLACK);
mPaintContour.setStrokeWidth(8);
mPaintGrid = new Paint();
mPaintContour = new Paint();
}
static int counter = 0;
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
counter++;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
TextView textView = (TextView) findViewById(R.id.textView1);
textView.setText(Integer.toString(counter++));
break;
case MotionEvent.ACTION_UP:
counter--;
invalidate();
break;
}
return true;
}
}
and my activity_board.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/backrepeat"
tools:context="com.example.splittheisland.BoardActivity"
tools:ignore="MergeRootFrame" >
<LinearLayout
android:id="#+id/LinearLayout1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button_board1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/board_button1"
android:onClick="onClickButtonBoard1"
android:text="MORE"
android:textColor="#FFFFFF"
android:textSize="40dp" />
<Button
android:id="#+id/button_board2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/board_button2"
android:onClick="onClickButtonBoard2"
android:text="HINT"
android:textColor="#FFFFFF"
android:textSize="40dp" />
<Button
android:id="#+id/button_board3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/board_button3"
android:onClick="onClickButtonBoard3"
android:text="START"
android:textColor="#FFFFFF"
android:textSize="40dp" />
<Button
android:id="#+id/button_board4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/board_button4"
android:onClick="onClickButtonBoard4"
android:text="END"
android:textColor="#FFFFFF"
android:textSize="40dp" />
</LinearLayout>
<LinearLayout
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/LinearLayout6"
android:layout_width="match_parent"
android:layout_height="88dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="#FFFFFF"
android:textSize="30dp" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="#FFFFFF"
android:textSize="30dp" />
</LinearLayout>
<com.example.splittheisland.BoardView
android:id="#+id/BoardView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
Unfortunately my program crashes... It is because:
TextView textView = (TextView) findViewById(R.id.textView1);
textView is null...
Why is that?
Your view can not find the TextView 'cause its not aware of the view hierarchy. Try implementing a setter/getter for the TextView inside your custom view, or consider something like:
LinearLayout llParent = (LinearLayout)getParent();
TextView textView2 = (TextView)llParent.findViewById(R.id.textView2);
I would prefer implementing a setter and using textView2 as a private member instead, so you don't have to get the reference every time.
Hope it helps.
mate this would never work.
BoardView doesnt contain textView1..
you can inflater TextView where you inflate the layout for example Activity or Fragment
since TextView and BoardView are siblings and not father/son relations it wont work.
<NumberPicker
android:id="#+id/firstSeekBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:background="#drawable/image3" />
how can i get value of numberpicker and move like TimePickerDialog
Here is my number picker which I use for date and time:
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.NumberPicker;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)//For backward-compability
public class NumberPickerMinMax extends NumberPicker
{
public NumberPickerMinMax(Context context)
{
super(context);
}
public NumberPickerMinMax(Context context, AttributeSet attrs)
{
super(context, attrs);
processAttributeSet(attrs);
}
public NumberPickerMinMax(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
processAttributeSet(attrs);
}
private void processAttributeSet(AttributeSet attrs)
{
//This method reads the parameters given in the xml file and sets the properties according to it
this.setMinValue(attrs.getAttributeIntValue(null, "min", 0));
this.setMaxValue(attrs.getAttributeIntValue(null, "max", 0));
}
}
Now you need to add 4 NumberPickerMinMax for each digit of time: HH:mm, here is my layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
<com.evapp.customViews.NumberPickerMinMax
android:id="#+id/TimePickerView_hour2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
min="0"
max="9"
android:layout_toLeftOf="#+id/textView1" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text=" - "
android:textAppearance="?android:attr/textAppearanceLarge" />
<com.evapp.customViews.NumberPickerMinMax
android:id="#+id/TimePickerView_hour1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_margin="2dp"
min="0"
max="2"
android:layout_toLeftOf="#+id/TimePickerView_hour2" />
<com.evapp.customViews.NumberPickerMinMax
android:id="#+id/TimePickerView_minutes1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
min="0"
max="5"
android:layout_toRightOf="#+id/textView1" />
<com.evapp.customViews.NumberPickerMinMax
android:id="#+id/TimePickerView_minutes2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
min="0"
max="9"
android:layout_toRightOf="#+id/TimePickerView_minutes1" />
</RelativeLayout>
</RelativeLayout>
Hope this is what you needed