Originally the number picker worked perfectly, but as soon as I put it in a listview item I was unable to enter numbers. When you select it to edit the text it sometimes brings up a text keyboard and sometimes a number keyboard. When pressing the numbers you can see it registering the letter keyboard is being pressed behind it.
Could this possibly be an issue with having a number picker in a listview item?
I've tried changing several attributes regarding focus and changing the input type of the edit text itself (which is indeed set to number correctly by default) and had no luck.
Number picker list item xml:
<?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">
<NumberPicker
android:id="#+id/timePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="32dp" />
<TextView
android:id="#+id/minutesText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_toEndOf="#+id/timePicker"
android:layout_centerVertical="true"
android:text="#string/test"
android:textColor="#android:color/white"
android:textSize="14sp" />
</RelativeLayout>
Then using this in the adapter for the listview to get the number picker item:
private View getNumberPickerView(int position, View convertView, ViewGroup parent) {
NumberPickerViewHolder holder;
if (convertView == null) {
convertView = mInflator.inflate(R.layout.number_picker_list_item, parent,false);
holder = new NumberPickerViewHolder();
holder.numberPicker = (NumberPicker) convertView.findViewById(R.id.timePicker);
holder.minutesText = (TextView) convertView.findViewById(R.id.minutesText);
convertView.setTag(holder);
}
else {
holder = (NumberPickerViewHolder) convertView.getTag();
}
if (position == mNumberPickerPos) {
holder.numberPicker.setMinValue(0);
holder.numberPicker.setMaxValue(300);
holder.minutesText.setText(R.string.test);
}
return convertView;
}
NumberPickerViewHolder is just an inner class that is used to reuse the listview items.
Edit: I also have an onValueChange listener for the number picker. I didn't think that would be causing the issue, but I checked anyway. Problem still happens with it removed.
Seems that nobody has an answer for this. What I ended up doing was taking the NumberPicker out of the ListView item and replacing it with an EditText that opened up a dialog box with the NumberPicker in it. It works perfectly since it is no longer part of the ListView item
Related
I'm getting frustrated about this:
When I define a custom ListView Layout,
Android Studio doesn't keep the background drawable I set in there.
Tried many things, and setting background programmatically doesn't work
since it's ignoring the layout_width which must be set to "wrap_content".
Actual style of background
Result without coding
If anyone could help me, I'd be very grateful !:)
EDIT:
I'm creating a Messenger and I want to display messages in a similar way to WhatsApp, where messages are shown in a listView. Depending on message is sent or received, items should be aligned ParentStart or ParentEnd.
But more importantly, if a message only contains a few chars, I don't want the ListItem Background to fill the entire screen, so it should be set dynamically.
I thought I could achieve this through simply setting wrap content in the parent layout file.
Files look like this:
<?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="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentEnd="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp"
tools:background="#drawable/background_message_sent">
//Here are TextViews
</LinearLayout>
</RelativeLayout>
Here is my ListViewAdapter, where I set background
(#drawable/background_message_sent/received) programmatically.
However, this covers the entire width of ListView, regardless of message length.
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
int currentUserID = 1;
int senderID = messagesArrayList.get(pos).getSenderID();
if (senderID == currentUserID){
View v = View.inflate(context, R.layout.layout_chat_message_sent, null);
v.setBackgroundResource(R.drawable.background_message_sent);
TextView tvMessageText = v.findViewById(R.id.tvMessageText);
TextView tvTimeStamp = v.findViewById(R.id.tvTimeStamp);
tvMessageText.setText(messagesArrayList.get(pos).getMessageText());
tvTimeStamp.setText(messagesArrayList.get(pos).getTimeStamp());
return v;
}
else {
View v = View.inflate(context, R.layout.layout_chat_message_received, null);
v.setBackgroundResource(R.drawable.background_message_received);
TextView tvMessageText = v.findViewById(R.id.tvMessageText);
TextView tvTimeStamp = v.findViewById(R.id.tvTimeStamp);
tvMessageText.setText(messagesArrayList.get(pos).getMessageText());
tvTimeStamp.setText(messagesArrayList.get(pos).getTimeStamp());
return v;
}
}
Well, after trying, I got the solution if anyone comes to this point:
You have to set your background drawable directly for each TextView, not for Parent Layouts.
These two Lines finally solved everything ^^
android:maxEms="14"
android:background="#drawable/background_message_sent"
<TextView
android:id="#+id/tvMessageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginEnd="0dp"
android:layout_marginTop="5dp"
android:layout_weight="0.22"
android:text="42456456456546"
android:textColor="#color/tentakelPrimary"
android:maxEms="14"
android:background="#drawable/background_message_sent"/>
I am trying for some hours now to get rid of the following problem and I search and applied the methods I found here and on other sites, but the result is still bad. Please have a look at the following screenshot:Screenshot of cut off text
This is my xml part:
<HorizontalScrollView
android:layout_width="367dp"
android:layout_height="355dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_marginTop="8dp"
android:fillViewport="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btn_search">
<ListView
android:id="#+id/listView_results"
style="#android:style/Widget.DeviceDefault.Light.ListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:background="#android:color/black"
android:clickable="true"
android:divider="#android:color/holo_orange_light"
android:dividerHeight="1dp"
android:scrollbars="horizontal|vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btn_search" />
</HorizontalScrollView>
And this is what I have written in my Java file:
`
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, titleList) {
#Override
public View getView(int position, View convertView, ViewGroup parent){
// Get the Item from ListView
View view = super.getView(position, convertView, parent);
TextView tv = (TextView) view.findViewById(android.R.id.text1);
// Set the text size in ListView for each item
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP,40);
tv.setSingleLine(true);
tv.setMaxLines(1);
tv.setHorizontallyScrolling(true);
tv.setHorizontalScrollBarEnabled(true);
//tv.setEllipsize(MARQUEE);
//tv.setMarqueeRepeatLimit(1000);
// Return the view
return view;
}
};`
As you can see I already tried the marquee option, but it did not show any effects.
Can anyone if he/she knows where to read about a possible solution, because the sources I found could not help me at all. If you have any suggestions, I would be happy to read them. I want to thank anyone in advance for their help. This is a university project and my first Android Application - some complications here and there ^^.
I was wondering if a TextView or a ListView or a HorizontalScollView has a limit in the width and if so where it can be expanded if that is an option.
Cheers
Durim
I found an answer now.
The HorizontalScrollView was creating a scrollable container that was exactly as width as the first entry of my ListView.
The Solutions I found:
1)
You bring your longest line to the first place in your list (depending on the font family that is used it still could make problems).
2)
I set the font family to "MONOSPACE" for all TextView inside my ListView and added spaces " " to the first line to make its number of characters equal to the number of characters of the longest line.
I hope this helps anyone some day. If you have any questions concerning this topic, let me know.
Cheers
Try
android:layout_width="wrap_content"
at listview.
I have a custom ListView item that has an ImageButton in it, and when I click it, the click events don't come through until the list item as a whole is interacted with, such as scrolling the list or tapping somewhere else on the list item. So for instance, if I click the ImageButton 5 times, nothing will happen, but then when I scroll the list, all 5 click events will come through simultaneously.
After a lot of research, I've come to find this is a common question, but none of the solutions I've found have worked for me so far. This question was quite helpful in learning some of the quirks of view interaction, and most other solutions I found used a similar approach to the accepted answer on that question, but unfortunately none of them worked for my particular situation.
So what I need to happen is to handle the click events for the ImageButton on the list item, as well as the click event for the list item itself. I've tried setting android:focusable="false" and android:focusableInTouchMode="false" on pretty much every view element involved in the display of this list. I've also tried setting these attributes programmatically. I also tried setting android:descendantFocusability="blocksDescendants" on several view elements including the ListView, the LinearLayout of the row item, and the CardView that contains all of this stuff.
The confusing part about all of this, is that I have this working just fine in another Activity of the same app. I have an ImageButton in a custom row layout of a ListView, and the onClick events work just fine for that. So it has to be something with my setup on this Activity. Here's some code:
The getView() of my custom BaseAdapter:
public View getView(int position, View convertView, ViewGroup parent) {
FavoritesItemViewHolder favoriteItem = favoritesList.get(position);
if(convertView == null) {
convertView = favoriteItem.getNewConvertView(parent);
} else {
if(favoriteItem.getConvertView() == null) {
convertView = favoriteItem.getNewConvertView(parent);
} else {
convertView = favoriteItem.getConvertView();
}
}
return convertView;
}
The view inflation of my individual view holders:
public View getNewConvertView(ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.favorites_list_item, parent, false);
TextView favoriteText = (TextView) convertView.findViewById(R.id.favoritesItemText);
favoriteText.setText(itemTitle);
//Here is where I'm setting the OnClickListeners for each row...
ImageButton clearButton = (ImageButton) convertView.findViewById(R.id.favoritesClearButton);
clearButton.setVisibility(View.VISIBLE);
if(itemTitle.equals(context.getResources().getString(R.string.no_favorites))) {
clearButton.setVisibility(View.INVISIBLE);
} else {
clearButton.setVisibility(View.VISIBLE);
clearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("CLEAR FAVORITE", "The clear button was just clicked on a favorites item...");
}
});
}
return convertView;
}
And here is the XML for my custom row layouts...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/favoritesListItemContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/favoritesItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_gravity="center_vertical"
android:textSize="16sp"
android:textColor="#android:color/black"
android:layout_weight="0.9"/>
<ImageButton
android:id="#+id/favoritesClearButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/ic_clear_x"
android:layout_gravity="center_vertical"
android:scaleType="centerInside"
android:adjustViewBounds="true"
android:background="#android:color/white"
style="?android:attr/borderlessButtonStyle"
android:layout_weight="0.1" />
</LinearLayout>
Any help would be appreciated. I'm just completely stumped here.
UPDATES
In this Activity, I'm using getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); in order to disable a SearchView and some other UI, and when the SearchView receives focus, suddenly my ListView items work as intended. So I'm guessing this has an issue with the ListView or the Window it's in having no focus, and so the click events don't come through until something on the screen receives focus.
What's strange is, when the keyboard is showing on the screen, I can click the list items and their ImageButtons and all the click events are handled correctly. But when I dismiss the keyboard, it breaks again.
There are known problems with ListView interfering with the touch events of views inside each item. You should switch to RecyclerView instead. ListView is seen as essentially deprecated for new apps with RecyclerView becoming its replacement.
I have ListAdapter which fills list with TextView of category and RadioButton which is to be checked. So, the problem is that I want user to define which category he wants through List and when he clicks on RadioButton, others should be unchecked and so on. I need to set somehow the ID of this RadioButtons and I'm doing that in getView(...) method in ListAdapter but when it calls for second time that method, he doesn't find that RadioButton and I get error while trying to set ID of this RadioButton view. I was debugging it, and first time it finds the view through method findViewById, but second time it doesn't.
I think I might know the problem for it -> when second time it goes to find the view by ID, it can't find it since I've put already other Identifier on the first call, but how can I set unique identifiers for my RadioButtons in the list then?
Here is my code:
getView:
public View getView(int index, View view, ViewGroup parent) {
if (view == null){
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.category_item, parent, false);
}
ListCategoryItem category = categories.get(index); // categories is list
TextView title = (TextView) view.findViewById(R.id.categoryTitle);
naziv.setText(kategorija.getNazivKategorije());
RadioButton radioBtn = (RadioButton) view.findViewById(R.id.categoryRadioButton);
radioBtn.setId(category.getIdCategory());
return view;
}
and here is my layout for category_item:
<?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="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/categoryTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:paddingTop="5dp"
/>
<RadioButton
android:id="#+id/categoryRadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:textSize="15sp"
android:onClick="onRadioButtonClick"/>
So, how to set unique identifier to my RadioButtons in view properly or can I make somehow group of RadioButtons which will care for itself that when other one is checked, others to be unchecked - something how in HTML is solved up.
By using setId(), you are changing the identifier associated with the RadioButton that is used to find it in the view tree. You should probably be using setTag() instead, which is documented here. This method allows you to attach some opaque data object to the view that can be retrieved later using the getTag() method.
Look at the code :-
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row = inflater.inflate(R.layout.country_row, parent, false);
}
return row;
}
The country row XML is :--
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="1" >
<TextView
android:id="#+id/nameOfCountry"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:text="Country" />
<CheckBox
android:id="#+id/checkBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:gravity="right" />
Now my question is once I check few of the check boxes in the list view and the scroll the list view, many other check boxes are automatically checked....
I know there is problem in getView but I'm not able to figure out where....
Also the problem is solved if I don't reuse the convert view. But that is a dumb idea...
Any thoughts.....
That's because the ListView does recycling of views. Essentially, it reuses some views that go off screen to make the new ones on screen to help with performance. There are 2 ways of dealing with this:
Set the values of the views before you return the row. For example, you would set the nameOfCountry and whether or not the checkbox is checked before the return view line. To do this though, you need to keep track of what is checked.
Don't use the convertview and just inflate a new view every time. This may result in a performance hit, but as long as the list isn't too long it shouldn't be too noticable (at least in my experience). Simply igonre the convertview value
You have to set the state of the checkbox explicitly if you reuse an old View.