<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
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()
);
}
}
Is there an idea to show numeric soft keyboard with % symbol programmatically?
For example I need to enter 13% in EditText, so I need numbers and percent symbol and I don't want to show letters in soft keyboard.
The below code shows only numbers and .
editText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
Any help is appreciated
For a customer i have allowed the '-' char within the layout.xml file (android:digits attribute, see bellow):
<EditText
android:id="#+id/searchText"
android:layout_width="match_parent"
android:layout_height="50dp"
android:maxLines="1"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:hint="#string/searchRecord_inputHint"
android:imeOptions="actionSearch"
android:inputType="number"
android:digits="1234567890-"
android:text="#={viewModel.textToSearch}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/switchSearchBy" />
Then, before searching i replace the '-' char occurences by '%'.
Of course, you must inform your users about this logic. Other solution is to build a simple Digits + '%' keyboard with buttons in a DialogFragment or even in your search layout directly.
Update: Integrated numeric keyboard view example
keyboard_num.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable name="myCls"
type="com.sample.keyboard.KeyboardNumeric"/>
</data>
<merge>
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stretchColumns="*"
android:columnCount="4"
android:rowCount="4">
<!--Row1-->
<Button
style="#style/KeyboardPluStyle"
android:id="#+id/button_7"
android:layout_width="130dp"
android:layout_height="64dp"
android:text="7"
android:layout_row="0"
android:layout_column="0"
android:onClick='#{(v)->myCls.onKey("7")}'/>
<Button
android:id="#+id/button_8"
android:layout_width="130dp"
android:layout_height="64dp"
android:text="8"
android:layout_row="0"
android:layout_column="1"
android:onClick='#{(v)->myCls.onKey("8")}'/>
<Button
style="#style/KeyboardPluStyle"
android:id="#+id/button_9"
android:layout_width="130dp"
android:layout_height="64dp"
android:text="9"
android:layout_row="0"
android:layout_column="2"
android:onClick='#{(v)->myCls.onKey("9")}'/>
<Button
android:id="#+id/button_clr"
android:layout_width="120dp"
android:layout_height="64dp"
android:layout_row="0"
android:layout_column="3"
android:foreground="#drawable/ic_clear"
android:onClick='#{(v)->myCls.onClickClear()}'/>
<!--Row2-->
<Button
android:id="#+id/button_4"
android:layout_width="130dp"
android:layout_height="64dp"
android:layout_row="1"
android:layout_column="0"
android:text="4"
android:onClick='#{(v)->myCls.onKey("4")}'/>
<Button
android:id="#+id/button_5"
android:layout_width="130dp"
android:layout_height="64dp"
android:layout_row="1"
android:layout_column="1"
android:text="5"
android:onClick='#{(v)->myCls.onKey("5")}'/>
<Button
android:id="#+id/button_6"
android:layout_width="130dp"
android:layout_height="64dp"
android:text="6"
android:layout_row="1"
android:layout_column="2"
android:onClick='#{(v)->myCls.onKey("6")}'/>
<Button
android:id="#+id/button_percent"
android:layout_width="120dp"
android:layout_height="64dp"
android:text="%"
app:autoSizeTextType="uniform"
app:autoSizeMinTextSize="12sp"
app:autoSizeMaxTextSize="50sp"
app:autoSizeStepGranularity="2sp"
android:textStyle="bold"
android:visibility="invisible"
tools:visibility="visible"
android:layout_row="1"
android:layout_column="3"
android:onClick='#{(v)->myCls.onKey("%")}'/>
<!--Row3-->
<Button
style="#style/KeyboardPluStyle"
android:id="#+id/button_1"
android:layout_height="64dp"
android:layout_width="130dp"
android:text="1"
android:layout_row="2"
android:layout_column="0"
android:onClick='#{(v)->myCls.onKey("1")}' />
<Button
style="#style/KeyboardPluStyle"
android:id="#+id/button_2"
android:layout_width="130dp"
android:layout_height="64dp"
android:text="2"
android:layout_row="2"
android:layout_column="1"
android:onClick='#{(v)->myCls.onKey("2")}'/>
<Button
style="#style/KeyboardPluStyle"
android:id="#+id/button_3"
android:layout_width="130dp"
android:layout_height="64dp"
android:layout_row="2"
android:layout_column="2"
android:text="3"
android:onClick='#{(v)->myCls.onKey("3")}'/>
<Button
style="#style/KeyboardPluStyleBlue"
android:id="#+id/button_enter"
android:layout_width="120dp"
android:layout_height="64dp"
android:layout_rowWeight="2"
android:layout_row="2"
android:layout_rowSpan="2"
android:layout_column="3"
android:foreground="#drawable/ic_enter"
android:onClick='#{(v)->myCls.onClickEnter()}' />
<!-- Row 4-->
<Button
style="#style/KeyboardPluStyle"
android:id="#+id/button_0"
android:layout_width="0dp"
android:layout_height="64dp"
android:text="0"
android:layout_row="3"
android:layout_column="0"
android:layout_columnSpan="2"
android:layout_columnWeight="1"
android:onClick='#{(v)->myCls.onKey("0")}'/>
<Button
style="#style/KeyboardPluStyleGray"
android:id="#+id/button_Cancel"
android:layout_width="130dp"
android:layout_height="64dp"
android:text="#string/adlb_dialog_cancel"
app:autoSizeTextType="uniform"
app:autoSizeMinTextSize="12sp"
app:autoSizeMaxTextSize="50sp"
app:autoSizeStepGranularity="2sp"
android:layout_row="3"
android:layout_column="2"
android:onClick='#{(v)->myCls.onClickCancel()}'/>
</GridLayout>
The KeyboardNumeric class:
package com.sample.keyboard;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.widget.LinearLayout;
import com.averydennison.foodxpress.R;
import com.sample.keyboard.databinding.KeyboardQtyBinding;
public class KeyboardNumeric extends LinearLayout {
private KeyboardNumBinding binding;
// constructors
public KeyboardNumeric(Context context) {
this(context, null, 0);
}
public KeyboardNumeric(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public KeyboardNumeric(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if(isInEditMode())//Uses LayoutInflater if you are in Android studio
LayoutInflater.from(getContext()).inflate(R.layout.keyboard_num, this, true);
else
init(getContext());
}
// Our communication link to the EditText
InputConnection inputConnection;
void init(Context context) {
binding= KeyboardNumBinding.inflate(LayoutInflater.from(context),(ViewGroup)this,true);
binding.setMyCls(this);
}
/**
* Call this on a key press
* #param value Key text value as String
*/
public void onKey(String value){
inputConnection.commitText(value, 1);
}
/**
* Call this when Enter key is pressed
*/
public void onClickEnter(){
inputConnection.performEditorAction(EditorInfo.IME_ACTION_DONE);
}
/**
* Call this when Clear key is pressed
*/
public void onClickClear(){
CharSequence currentText = inputConnection.getExtractedText(new ExtractedTextRequest(), 0).text;
CharSequence beforCursorText = inputConnection.getTextBeforeCursor(currentText.length(), 0);
CharSequence afterCursorText = inputConnection.getTextAfterCursor(currentText.length(), 0);
inputConnection.deleteSurroundingText(beforCursorText.length(), afterCursorText.length());
}
/**
* Clall this when Cancel key is pressed
*/
public void onClickCancel(){
inputConnection.performEditorAction(EditorInfo.IME_ACTION_SEND);
}
/** The activity (or some parent or controller) must give us
* a reference to the current EditText's InputConnection
*/
public void setInputConnection(InputConnection ic) {
this.inputConnection = ic;
}
}
EditText that avoids Soft input keyboard to be shown:
package com.sample.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
public class CustomEditText extends
androidx.appcompat.widget.AppCompatEditText {
public CustomEditText(Context context) {
super(context);
}
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private boolean softInputEnabled=false;
public void setSoftInputAllowed(boolean enabled){
softInputEnabled=enabled;
}
public boolean getSoftInputAllowed(){
return softInputEnabled;
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
preventSofInputShown();
lockContextMenu();
}
private void lockContextMenu(){
this.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//to keep the text selection capability available ( selection cursor)
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
//to prevent the menu from appearing
menu.clear();
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
});
}
#Override
public boolean performClick() {
/* synchronized (this){
//Find the currently focused view, so we can grab the correct window token from it.
View view = getRootView().findFocus();
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null)
view = this;
else
this.clearFocus();
InputMethodManager imm = (InputMethodManager)getContext().getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}*/
if(softInputEnabled)
return false;
else
return true;
}
private void preventSofInputShown(){
this.setOnTouchListener((v, event) -> {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
return performClick();
default:
return false;
}
});
}
}
fragment_search.xml using CustomEditText + Keyboard:
<?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">
<com.sample.views.CustomEditText
android:id="#+id/txtQty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:clickable="true"
android:ems="10"
android:inputType="number"
android:longClickable="false"
android:textSize="40sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.sample.KeyboardNumeric
android:id="#+id/keyboardFull"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Finally, in your SearchFragment code (Attached to fragment_search.xml), just add this: (ie: in onCreate after inflating view)
// pass the InputConnection from the EditText to the keyboard
KeyboardNumeric keyboard = view.findViewById(R.id.keyboardFull);
EditText txtQty=view.findViewById(R.id.txtQty);
InputConnection ic = txtQty.onCreateInputConnection(new EditorInfo());
KeyboardQty.setInputConnection(ic);
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>
I have made a CustomTypeDialog class and what I want is to use EditText which is not in the active layout. I get a nullpointer exception when I try to click one of the buttons, which I think is because they are not in the active layout. Can you help me solve this? The dialog is called in an activity from another class.
package dk.droidrun.droidrunapp;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
public class CustomTypeDialog extends Dialog {
ImageButton routeType;
EditText txtType;
Button imageRun, imageBike, imageWalk;
public CustomTypeDialog(final Context context) {
super(context);
this.setContentView(R.layout.customtype_dialog);
routeType = (ImageButton)findViewById(R.id.saveRoute_activityType);
txtType = (EditText)findViewById(R.id.saveRoute_typeTxt);
imageRun = (Button)findViewById(R.id.dialog_btn1);
imageBike = (Button)findViewById(R.id.dialog_btn2);
imageWalk = (Button)findViewById(R.id.dialog_btn3);
setTitle("Select activity type");
show();
imageRun.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
txtType.setText("Run");
routeType.setBackgroundResource(R.drawable.track_run);
}
});
imageBike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
txtType.setText("Bike");
routeType.setBackgroundResource(R.drawable.track_bike);
}
});
imageWalk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
txtType.setText("Walk");
routeType.setBackgroundResource(R.drawable.track_walk);
}
});
}
}
This is my customtype_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".AutoMode"
android:background="#color/black" >
<RelativeLayout
android:id="#+id/dialog_relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_above="#+id/dialog_relativeLayout2"
android:layout_centerHorizontal="true" >
<Button
android:id="#+id/dialog_btn1"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="3dp"
android:background="#drawable/track_run"
android:layout_alignRight="#+id/dialog_relativeLayout1"
android:layout_alignTop="#+id/dialog_relativeLayout1"
/>
<Button
android:id="#+id/dialog_btn2"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="3dp"
android:background="#drawable/track_bike"
android:layout_alignTop="#+id/dialog_relativeLayout1"
android:layout_toRightOf="#+id/dialog_btn1"
/>
<Button
android:id="#+id/dialog_btn3"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="3dp"
android:layout_toRightOf="#+id/dialog_btn2"
android:background="#drawable/track_walk"
/>
</RelativeLayout>
</RelativeLayout>
saveroutes.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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/black"
tools:context=".SaveRouteActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:text="#string/saveRoute"
android:textColor="#color/white"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:layout_marginTop="10dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#7a0100"
android:text="Enter a name for the route" />
<EditText
android:id="#+id/saveRoute_nameRoute"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ems="10"
android:hint="#string/saveRoute_name"
android:textColor="#color/white"
android:background="#4e4751"
android:inputType="textPersonName" >
</EditText>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#7a0100"
android:text="Describe your route" />
<EditText
android:id="#+id/saveRoute_desciptionTxt"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ems="10"
android:hint="#string/saveRoute_description"
android:textColor="#color/white"
android:background="#4e4751"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#7a0100"
android:text="Activity type (e.g. running)"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal" >
<EditText
android:id="#+id/saveRoute_typeTxt"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginTop="17dip"
android:ems="10"
android:layout_marginLeft="30dp"
android:hint="#string/saveRoute_type"
android:textColor="#color/white"
android:background="#4e4751" >
<requestFocus />
</EditText>
<ImageButton
android:id="#+id/saveRoute_activityType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/track_walk" />
</LinearLayout>
<Button
android:id="#+id/saveRoute_saveBtn"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:background="#color/white"
android:text="#string/saveRoute_savebutton" />
<Button
android:id="#+id/saveRoute_cancelBtn"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:background="#color/white"
android:text="#string/saveRoute_cancel" />
</LinearLayout>
You cannot access views from another layout (your activity) using findViewById within the dialog view.
You need to add a callback listener for when the buttons on your dialog are clicked:
public interface OnDialogClickListener {
void onDialogImageRunClick();
}
public class CustomTypeDialog extends Dialog {
private final OnDialogClickListener listener;
public CustomTypeDialog(final Context context, OnDialogClickListener listener) {
this.listener = listener;
}
....
imageRun.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onDialogImageRunClick();
}
);
}
Then when you create your dialog in your Activity where you have access to the view:
new CustomTypeDialog(context, new CustomTypeDialog.OnDialogClickListener() {
#Override
public void onDialogImageRunClick() {
txtType.setText("Run");
routeType.setBackgroundResource(R.drawable.track_run);
}
});
I want to do a custom view coming from an XML.
Here's my XML :
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/movieTitle"
android:text="#string/movietitle"
android:textSize="35dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
/>
<com.galite.headliner.views.LoaderImageView
android:id="#+id/moviePoster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/movieTitle"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:contentDescription="#string/poster"
/>
<TextView
android:id="#+id/movieDescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/description"
android:layout_below="#id/moviePoster"
android:gravity="center"
/>
</RelativeLayout>
And i want to inflate to a custom view because i need to use methods like onClick and everything.
Here's my constructor :
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
initializeView();
}
public void initializeView(){
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.movie, null);
}
How can i make MyView equal to v ?
You'll have to attach the inflated view v to MyView like this:
v = inflater.inflate(R.layout.movie, this, true);
If you want that exact layout then make MyView to extend RelativeLayout and modify the xml layout like this:
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="#+id/movieTitle"
android:text="#string/movietitle"
android:textSize="35dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
/>
<com.galite.headliner.views.LoaderImageView
android:id="#+id/moviePoster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/movieTitle"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:contentDescription="#string/poster"
/>
<TextView
android:id="#+id/movieDescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/description"
android:layout_below="#id/moviePoster"
android:gravity="center"
/>
</merge>