Custom Android Spinner Layout Issue - java

I am customizing an android Spinner Widget. I am trying to use different background colors against the list items. This is working, but when there are more items in the spinner control, the list items are not occupying the full space horizontally, thus showing white space on the popup view.
For small number of items, it is working fine.
I have tried custom and default Layout customizations.
JAVA Custom Spinner View Code
#Override
public View getView(int pos, View view, ViewGroup parent)
{
LayoutInflater objInflater = LayoutInflater.from(context);
view = objInflater.inflate(R.layout.spinner_item_colored, null);
LinearLayout llOption = (LinearLayout) view.findViewById(R.id.llOption);
TextView tvOption = (TextView) view.findViewById(R.id.tvOption);
if (alDefects.get(pos).sNature.equalsIgnoreCase("1"))
llOption.setBackgroundColor(getResources().getColor(R.color.majorDefect));
else if (alDefects.get(pos).sNature.equalsIgnoreCase("2"))
llOption.setBackgroundColor(getResources().getColor(R.color.criticalDefect));
else
llOption.setBackgroundColor(getResources().getColor(R.color.minorDefect));
tvOption.setTextColor(getResources().getColor(R.color.white));
tvOption.setText(alDefects.get(pos).sDefect);
return view;
}
XML Code:
<LinearLayout
android:id="#+id/llOption"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_margin="0dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/tvOption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical|left"
android:singleLine="false"
android:textColor="#444444"
android:textSize="13dp" />
I want the spinner popup to use full available width for Background color when there is a scrollbar.
Please click this Link to see the Sample Output

When you use weight you should set android:layout_width="0dp"

Related

Is there a good way to inflate cardview layout with another linear in a loop?

I'm try to create a ListView with CardView. CardView contains always 3 rows with some info, but after that it got 2n rows that looks like:
- position, name;
- image, data, image, data.
I'm using for this task object, that contains:
- object with data, that will always fill fist 3 rows;
- list of object, that i use for 2n rows.
I've tried already:
- swapping RecyclerAdapter to ArrayAdapter (helps with visibility that I change too, but not with inflating);
- creating a method that will handle all logic related to inflating that layout
- inflating inside onBindViewHolder/getView
I will paste version with inflating CardView in another method:
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
/*inflating layout and fill it with data from first object*/
View listItem = convertView;
if(listItem == null)
listItem = LayoutInflater.from(context).inflate(R.layout.card,parent,false);
//add data
//if needed to make sure that inflating will occur once. list is
//LinearLayout inside CardView, current is entire object
if(list.getChildCount() < 1)
addList(list, current);
//setting click listeners and returning view
}
private void addList(ViewGroup parent, ListItem current){
for (Item var : ListItem.getItemList()) {
View layout = LayoutInflater.from(context).inflate(R.layout.card_part, parent, false);
//setting data
ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = LinearLayout.LayoutParams.WRAP_CONTENT;
params.width = LinearLayout.LayoutParams.WRAP_CONTENT;
layout.setLayoutParams(params);
parent.addView(layout);
}
}
#EDIT: CardView
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#color/colorPrimary"
android:layout_margin="15dp"
app:cardCornerRadius="5dp"
app:cardElevation="25dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/id"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/text"
android:id="#+id/name"
android:textSize="20sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/text"
android:id="#+id/type"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/text"
android:layout_weight="1"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_expand"
tools:ignore="ContentDescription"
android:id="#+id/show_list"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_hide"
tools:ignore="ContentDescription"
android:visibility="gone"
android:id="#+id/hide_list"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/list"
android:visibility="gone">
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Actual results:
- if i comment
if(list.getChildCount() < 1)
data fill be sometimes added few time, not only from correct object.
- now with that if layout is inflating with wrong data.
Expected result:
Inflating inside CardView add data that is correct for object and connected to it list of objects.
#EDIT2:
I've tried to just create that part of View manually instead of using LayoutInflater. That does not change anything.
After some break from this topic I found way to do it. Adapter reusing old View on getView/onBindViewHolder. If Linear Layout that conatins earlier list of others elements like TextView, ImageView etc. was not cleared before adding new elements, old will stay.
The solustion is to remove old ones. On Linear Layout I needed to call removeAllViews() before adding new elements.

Skobbler callout tail imageview displayed incorrectly Android SDK 2.5.1

I have code that adds a custom annotation callout view to be displayed whenever an annotation is selected my Skobbler mapview.
#Override
public void onAnnotationSelected(final SKAnnotation annotation) {
...
mapPopup = mapHolder.getCalloutView();
// set the callout view’s background color
mapPopup.setViewColor(Color.WHITE);
View view = getLayoutInflater().inflate(R.layout.map_callout, null);
...
mapPopup.setCustomView(view);
// setting 2nd parameter to 'true' will cause tail to be displayed
mapPopup.showAtLocation(annotation.getLocation(), true);
...
}
I also request in the showAtLocation() call that the callout view be displayed with the "tail" imageview. However, when I test in the app, I see that the tail appears at the top of my map_surface_holder RelativeLayout container instead of at the bottom of the FrameLayout container that displays the callout popup view.
When I pan the map, I can see that the tail view moves left and right relative to the movement of the callout view, but it remains aligned to the top of the map_surface_holder container, never moving up or down.
Do I need to add some code somewhere to make the tail image view aware of where it should be placed in the y-axis direction of the RelativeLayout container?
I did try adding a call to mapPopup.setVerticalOffset(offset) to see if that had any effect, but the tail image remained locked to the top of the screen.
One other difference I could see between my custom callout view and the default one provided by the Skobbler is that the standard view is a RelativeLayout container while my implementation is a FrameLayout. However, I'm not sure that it should matter since the Tail ImageView here is being added to the parent of my callout view, not as a child.
Thank you in advance for any help in the matter, and let me know if any additional details would be helpful.
Thanks!
We've tried to reproduce the problem with both 2.5.1 and 3.X - but we weren't able.
Here is the code we used:
//MapActivity
#Override
onCreate(Bundle savedInstanceState)
{
…
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mapPopup = mapViewGroup.getCalloutView();
View view = inflater.inflate(R.layout.layout_popup, null);
popupTitleView = (TextView) view.findViewById(R.id.top_text);
popupDescriptionView = (TextView) view.findViewById(R.id.bottom_text);
mapPopup.setCustomView(view);
…
}
#Override
public void onAnnotationSelected(final SKAnnotation annotation) {
if (navigationUI.getVisibility() == View.VISIBLE) {
return;
}
// show the popup at the proper position when selecting an
// annotation
int annotationHeight = 0;
float annotationOffset = annotation.getOffset().getY();
switch (annotation.getUniqueID()) {
case 10:
annotationHeight =(int) (64 * getResources().getDisplayMetrics().density);
popupTitleView.setText("Annotation using texture ID ");
popupDescriptionView.setText(null);
break;
case 11:
annotationHeight = customView.getHeight();
popupTitleView.setText("Annotation using custom view");
popupDescriptionView.setText(null);
break;
}
mapPopup.setVerticalOffset(-annotationOffset + annotationHeight / 2);
mapPopup.showAtLocation(annotation.getLocation(), true);
}
//layout_popup.xml
<ImageView
android:id="#+id/left_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:clickable="true"
android:padding="5dp"
android:src="#drawable/icon_map_popup_navigate" />
<LinearLayout
android:id="#+id/mid_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/left_image"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp"
android:weightSum="1" >
<TextView
android:id="#+id/top_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="Title text"
android:textColor="#color/black"
android:textSize="18dp"
android:textStyle="bold" />
<TextView
android:id="#+id/bottom_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:linksClickable="true"
android:text="Subtitle text"
android:textColor="#color/black"
android:textSize="14dp" />
</LinearLayout>

Can't manage to change text color on Spinner

I've tried a lot of other answers on SO, none of them seem to work for me. I'm not sure what I did wrong.
Here's my xml:
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/product_category_spinner"
android:theme="#style/AppartmentBlue" />
And here's my Java (it's a DialogFragment extending class):
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_product_dialog, container, false);
Spinner productCategory = (Spinner) v.findViewById(R.id.product_category_spinner);
ArrayAdapter<String> spinnerAdapter =
new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.category_array));
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
productCategory.setAdapter(spinnerAdapter);
// setCancelable(false);
return v;
}
The thing is, the text is white on very bright gray. It came that way by default, if it came in black foreground I wouldn't need to touch it. Why's it doing this? My theme extends from Theme.Holo.Light.DarkActionBar.
I don't wanna set it at runtime, I'm gonna have a lot of spinners and I want it to be global across the app, with the option for me to add later themes.
I hope this helps:
My Spinner:
<Spinner
android:id="#+id/spinner_cat"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:layout_marginStart="#dimen/left_margin_large"
android:layout_marginLeft="#dimen/left_margin_large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"/>
Setting up the adapters:
private final int _singleItemRes = R.layout.simple_spinner_item;
private final int _dropdownRes = R.layout.simple_spinner_dropdown_item;
ArrayAdapter<String> adapter = new ArrayAdapter<String>(_handler.getContext(), _singleItemRes, getTitles());
adapter.setDropDownViewResource(_dropdownRes);
simple_spinner_item.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="#color/actionbar_text"
android:textSize="20sp"
android:textStyle="normal"/>
simple_spinner_dropdown_item.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#color/primary_dark"
android:ellipsize="marquee"
android:layout_centerVertical="true"
android:singleLine="true"
android:paddingRight="#dimen/left_margin_small"
android:paddingLeft="#dimen/left_margin_small"
android:textColor="#color/actionbar_text"/>
Let me know if I am missing anything from the answer and I will add it in.

Setting the number of viewable item count in listView

Is there a way to set the viewable item count for a listview? or am I obliged to set the height for the listview?
For instance, I got a list that includes 9 items. I only want 4 of them to appear at first. Then user needs to scroll to see other items.
list_anlam.xml
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="1dp"
android:background="#android:color/darker_gray" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/title_popup_hikayeoku" />
<EditText android:id="#+id/kelime_text"
android:inputType="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ListView android:id="#+id/list_anlam"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
<Button
android:id="#+id/button_sec"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/button_popup_hikayeoku" />
</LinearLayout>
list_item.xml :
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:padding="10dp" />
Where I fill items into listview : HikayeOkuActivity.java is
String[] anlamlar = null;
anlamlar = MainActivity.dbM.ilkAnlamGetir(selectedText);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item,anlamlar);
anlamList.setAdapter(adapter);
popupWindow.showAsDropDown(mainLayout, touchedX,touchedY);
Yes, you need to get the height of the listview. In your onCreate you do something like:
listview.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
height = listView.getHeight();
}
In the getView method of your adapter you then use the height divided by four to set the height of each list item.
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = activity.getLayoutInflater();
View rowView = inflater.inflate(R.layout.item_layout, parent, false);
rowView.setMinHeight(height/4);
return rowView;
}
Now this should preferably be done with a ViewHolder, but that's not the topic here.
Basically, the height of each view must be 1/4 of the height of your ListView. If you want to support all device resolutions, you have to calculate it. If you need more info about that, add a comment and I will explain it in detail.
Important for details, what kind of Adapter are you using for your ListView?
Correct me if I'm wrong, but..
you could also use an android:WEIGHTSUM and android:WEIGHT parameters in your xml layouts. Set android:weightsum=1 for parent view (your ListView) and android:weigth=0.25 for child views (layout of ListView items). In this case you don't have to calculate heights of your viewables.

Android. Add controls programmatically

I have layout with controls:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/contact_phones_layout_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/contact_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:inputType="phone" />
<Spinner
android:id="#+id/contact_phone_type"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
And I want to inflate it into another layout on the fragment. Quantity of these controls depends on values in a array. Array contains controls objects. So every time onCreateView rises I filled the layout from the array:
private void addLine(PhoneLine line) {
LinearLayout layout = (LinearLayout) mLayout.findViewById(R.id.contact_phones_layout);
View view = line.getParent();
((ViewGroup) view.getParent()).removeView(view);
layout.addView(view, layout.getChildCount() - 1);
setButtonVisible(false);
}
if line is null controls are created this way:
private void addLine() {
LinearLayout layout = (LinearLayout) mLayout.findViewById(R.id.contact_phones_layout);
View view = inflater.inflate(R.layout.contact_phone_line, layout, false);
EditText phoneEditText = (EditText) view.findViewById(R.id.contact_phone);
Spinner phoneType = (Spinner) view.findViewById(R.id.contact_phone_type);
phoneLines.add(new PhoneLine(phoneEditText, phoneType, view));
layout.addView(view, layout.getChildCount() - 1);
}
But after that I get same values in all EditText/Spinner controls, values equal to last element in the array. What can be wrong? May be there is more pure way to add controls dynamically?
I fixed it by adding controls when onResume rises, not onCreateView. But I still don't understand why onCreateView changes all values.

Categories

Resources