I have a GridView with items that change background resource when an item is clicked.
At the same time I want to animate a layouts position, when I do this however, the background resource for gridView item doesn't change the first time the animation is played
What i want to happen:
item is clicked
1. item backgroundResource is changed
2.a hidden layout is shown and animated
what actually seems to be happening is:
First time when the layout is still hidden the animation is shown but the background resource of the clicked item is not changed, any subsequent item clicks set the resource as it should and the animation works.
EDIT:
I've played around a little more and the issue seems to be the visibility "gone" rather than the animation, if i set the layout to Visibility="invisible" then the resource is applied, so it seems that if the gridView is moved in any kind of way (gridView is beneath the hidden layout that i wan't to show) the resource is ignored?
i.e.:
<LinearLayout
android:id="#+id/dateDetailContainer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="invisible"> //instead of gone
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is a Placeholder for the chosen dates' items, it's gonna look super awesome once i implement this shit"
android:textSize="15sp"
/>
</LinearLayout>
this is the onItemClickListener:
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
scaleAnimateHeight(findViewById(R.id.dateDetailContainer));
setSelectedBackground(v, gridview);
}
scaleAnimateHeight():
private void scaleAnimateHeight(View v){
LinearLayout tv = (LinearLayout) v;
tv.setVisibility(View.VISIBLE);
Animation expand = AnimationUtils.loadAnimation(this, R.anim.from_left);
tv.startAnimation(expand);
}
setSelectedBackground():
private void setSelectedBackground(View v, GridView gridview ){
v.setBackgroundResource(R.drawable.back_selected);
}
anim.from_left.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="250"
android:fromXDelta="-100%"
android:toXDelta="0%" >
</translate>
</set>
and the layout:
<LinearLayout
android:id="#+id/dateDetailContainer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is a Placeholder"
android:textSize="15sp"
/>
</LinearLayout>
Edit:
Instead of:
v.setBackgroundResource(R.drawable.back_selected);
try:
setImageDrawable(R.drawable.back_selected);
or
setImageDrawable(getResources().getDrawable(R.drawable.back_selected));
Try reversing your method calls within your listener. You are setting the resource after you change the visibility and run the animation, so it won't show until you click it the second time.
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//HERE
setSelectedBackground(v, gridview);
scaleAnimateHeight(findViewById(R.id.dateDetailContainer));
}
Related
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"
I'm using a custom layout for a Spinner DropDownview, it has a brown background with white letters. There are some white stripes appearing at the bottom of the view1, that I want to remove but I don't know how neither why they are appearing;
here are the code that I'm using for the spinner_dropdown_item:
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="#dimen/dropdownListPreferredItemHeight"
android:background="#color/marrom"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:minHeight="#dimen/txt_min_height"
android:paddingEnd="#dimen/md_keylines"
android:paddingStart="#dimen/md_keylines"
android:singleLine="true"
android:textAllCaps="true"
android:textColor="#color/white"
android:textSize="#dimen/text_subtitle"
tools:text="spinner dropdown item" />
and the getDropdownView inside the spinner adapter:
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
T element = elements.get(position);
convertView = LayoutInflater.from(parent.getContext()).inflate(getDropdownLayout(), parent, false);
final TextView textView = (TextView) convertView;
textView.setText(getDisplayName(element));
return textView;
}
where the function getDropdownLayout returns the layout above
After some research, I stumbled upon a suggestion:spinner with a rectangular border.
Create 9 patch image(Rectangle Box) which helps you to set the spinner with different resolution.
After creating 9 patch image use it as a background of the Spinner.
Here is a link that makes creating that 9pacth image simple:http://inloop.github.io/shadow4android/
Here is my example:
I have a listview which occupies all the space of the layout IN THEORY, but actually it occupies only half of the layout because it has got only 5 elements and it doesn't cover all the screen. I'd like to know when I touch OUTSIDE of the listview. I tried to create a clicklistener method for the layout of the listfragment which contains the list, but it is never used because IN THEORY the listview occupies all the layout, so the click isn't found. It is the same for the layout of the activity more or less. In that case the click is found only on the edges, so I can't find a method to solve my problem.
Here is the fragment layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list" />
Here is the activity layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.utente.actionbar.MainActivity">
<Button
android:text="MULTI"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="26dp"
android:id="#+id/button" />
<Button
android:text="SINGOLO"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/button"
android:layout_alignLeft="#+id/button"
android:layout_alignStart="#+id/button"
android:layout_marginBottom="25dp"
android:id="#+id/button2" />
IN THEORY the listview occupies all the layout
Not a theory, that is exactly what happens; by using android:layout_height="match_parent" the View will always take the full screen height.
listView.setOnClickListener would work if you want to see if you clicked anywhere in the ListView, but you typically would instead want listView.setOnItemClickListener to see if you have clicked on any single item, and not the entire list.
Refer: difference between onClickListener and onItemClickListener
If you really want to shrink the ListView, then android:layout_height="wrap_content" is an option, but I'm not sure that works without content actually being loaded into that View since the content wrapping is applied at inflation-time, which since it has no adapter set, can't be done.
If you are needing to detect a listener literally "outside the ListView", then you need to set some type of click / touch listener on the rootView of that Fragment.
public View onCreateView(...) {
rootView = inflater.inflate(...);
listView = ...;
listView.setOnTouchListner(...
#Override
public boolean onTouch(View v, MotionEvent event) {
return false; // Says that click was not handled here.
}
});
rootView.setOnTouchListner(...
// TODO: Check if click landed outside the ListView
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() != android.R.id.listView) { // Not the list
if (event.getAction() == MotionEvent.ACTION_UP) {
// Up action more reliable than "down"
return true;
}
}
}
);
return rootView;
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content" <!-- Or specific height -->
android:id="#android:id/list" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/clickView" />
</LinearLayout>
In Fragmet
public View onCreateView(...) {
rootView = inflater.inflate(...);
View clickView = rootView.findViewById(...);
clickView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do something here
}
});
return rootView;
}
I guess this solves your problem.
I'm adding views programatically into FrameLayout:
public class PixelGridView extends FrameLayout {
...
public void addViewWithoutCoords(TableView view, int column, int row) {
float x = column * mCellSideSize;
float y = row * mCellSideSize;
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
view.setLeft(0);
view.setTop(0);
view.setX(x);
view.setY(y);
view.setVisibility(VISIBLE);
addView(view);
}
...
}
However, all they are somehow invisible. getChildCount() returns count with all of them. getVisibility() for each added view also returns VISIBLE.
I can drag'n'drop such views from another ViewGroup into my Framelayout and when I do this, all earlier added views become visible.
view layout file:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="#+id/ivTable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<EditText
android:id="#+id/ivTableName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#color/style_table_grey"
android:textColor="#android:color/white"/>
</RelativeLayout>
Even If I add new view without drag everything become visible.
The item view of the FrameLayout and RelativeLayout can be overlapping. If two item views are in the same positions of FrameLayout, the first loaded item will be covered by the later item.
Try turn on the show layout bounds in developer option of your android devices,and find the position of your item.
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.