I'm trying to figure out how to set up a custom listSelector to my listView. The code is more-or-less copy&paste from solutions that worked for others in stackoverflow, but it doesn't work for me.
When I turn on the CAB mode, then I can select and deselect the items, and I see the number of selected items in the CAB navbar, but I don't see any indication in the list. I would like to see which items are selected. Any idea why it doesn't work?
layout/category_list.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:id="#+id/categories_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/category_browser"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_selector"
android:drawSelectorOnTop="true"
tools:listitem="#layout/category_list_item" >
</ListView>
<include layout="#layout/ad"/>
</LinearLayout>
layout/category_list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<com.fletech.smartbaby.api.CheckableLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/category_browser_list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="fill"
android:clickable="true"
android:gravity="fill"
android:orientation="horizontal">
<ImageView
android:id="#+id/category_item_icon"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_gravity="fill"
android:layout_weight="0"
android:background="#ffffff"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/category_browser_list_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:paddingLeft="10dp"
android:paddingRight="10dp"
tools:text="Category name"
android:textColor="#000000"
android:textSize="24sp" />
<include layout="#layout/category_features"
android:layout_centerInParent="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
/>
<include layout="#layout/category_status"
android:layout_centerInParent="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
/>
</com.fletech.smartbaby.api.CheckableLinearLayout>
drawable/list_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#40777777"/>
</shape>
</item>
<item android:state_long_pressable="true">
<shape android:shape="rectangle">
<solid android:color="#400000ff"/>
</shape>
</item>
<item android:state_checkable="true">
<shape android:shape="rectangle">
<solid android:color="#400000ff"/>
</shape>
</item>
<item android:state_checked="true">
<shape android:shape="rectangle">
<solid android:color="#800000ff"/>
</shape>
</item>
</selector>
and CheckableLinearLayout.java:
package com.fletech.smartbaby.api;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
//import android.support.v7.widget.LinearLayoutCompat; // do I need this? I can't see any difference
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Checkable;
import android.widget.LinearLayout;
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private static final String TAG = CheckableLinearLayout.class.getSimpleName();
private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
private boolean mChecked;
public CheckableLinearLayout(Context context) {
super(context);
}
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void setChecked(boolean checked) {
Log.v(TAG, "setChecked: " + checked);
if (mChecked != checked) {
mChecked = checked;
refreshDrawableState();
}
}
#Override
public boolean isChecked() {
return mChecked;
}
#Override
public void toggle() {
Log.v(TAG, "toggle: " + mChecked + " -> " + (!mChecked));
setChecked(!mChecked);
}
#Override
// not sure if needed, as it seems to work without this as well
public boolean performClick() {
Log.v(TAG, "performClick");
toggle();
return super.performClick();
}
#Override
// this might be unnecessary
protected void drawableStateChanged() {
Log.v(TAG, "drawableStateChanged");
super.drawableStateChanged();
final Drawable drawable=getBackground();
if(drawable!=null)
{
final int[] myDrawableState=getDrawableState();
drawable.setState(myDrawableState);
invalidate();
}
}
#Override
protected int[] onCreateDrawableState(int extraSpace) {
Log.v(TAG, "onCreateDrawableState: " + extraSpace);
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
#Override
protected Parcelable onSaveInstanceState() {
SavedState result = new SavedState(super.onSaveInstanceState());
result.checked = mChecked;
return result;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setChecked(ss.checked);
}
protected static class SavedState extends BaseSavedState {
protected boolean checked;
protected SavedState(Parcelable superState) {
super(superState);
}
#Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(checked ? 1 : 0);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
private SavedState(Parcel in) {
super(in);
checked = in.readInt() == 1;
}
}
}
I took me more than a week to find out why this thing that works for everyone doesn't work for me. The answer is simple. I hope it'll help others.
The solution was to change the order of the items in the selector xml. The item without any states has to be the last one:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_long_pressable="true">
<shape android:shape="rectangle">
<solid android:color="#400000ff"/>
</shape>
</item>
<item android:state_checkable="true">
<shape android:shape="rectangle">
<solid android:color="#400000ff"/>
</shape>
</item>
<item android:state_checked="true">
<shape android:shape="rectangle">
<solid android:color="#800000ff"/>
</shape>
</item>
<!-- the item without any states has to be the last: -->
<item>
<shape android:shape="rectangle">
<solid android:color="#40777777"/>
</shape>
</item>
</selector>
The reason is that it seems that the parser looks for the 1st item in the xml file that matches. It means that if you have items with different number of states, then you should always have those that have more states defined in the top of the xml. For example:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checkable="true" android:state_long_pressable="true">
<shape android:shape="rectangle">
<solid android:color="#ffff00"/>
</shape>
</item>
<item android:state_long_pressable="true">
<shape android:shape="rectangle">
<solid android:color="#ff0000"/>
</shape>
</item>
<item android:state_checkable="true">
<shape android:shape="rectangle">
<solid android:color="#00ff00"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#40777777"/>
</shape>
</item>
</selector>
This way, and only this way, you'll see a different color on items that are:
- both checkable and long_pressable
- checkable, but not long_pressable
- long_pressable but not checkable
- everything else
Related
I am adding the border around tabs as shown in the second image.
I am able to add the borders on top and the bottom as shown in first image but not able to add the border on left/right side of each tab individually.
main_activity.xml
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/tab_border"
android:theme="#style/AppTheme.ActionBar"
android:visibility="invisible"
app:tabIndicatorColor="#color/colorPrimary">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"
app:layout_constraintTop_toTopOf="parent" />
#drawable/tab_border.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#efefef"/>
<stroke android:width="2dp" android:color="#c0c6cc"/>
<corners android:radius="0dp" />
<padding android:left="10dp" android:top="5dp"
android:right="10dp" android:bottom="5dp" />
</shape>
I am adding the tabs programmatically in activity class as i have to decide the no of tabs on run-time.
Using CustomTabLayout:
public class CustomTabLayout extends TabLayout {
public CustomTabLayout(Context context) {
this(context, null);
}
public CustomTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
#Override
public void setupWithViewPager(#Nullable ViewPager viewPager) {
super.setupWithViewPager(viewPager);
initCustomTab();
}
#SuppressWarnings({ "ConstantConditions" })
private void initCustomTab() {
int totalTab = getTabCount();
for (int i = 0; i < totalTab; i++) {
Tab tab = getTabAt(i);
if (tab == null) continue;
View view = LayoutInflater.from(getContext())
.inflate(R.layout.item_custom_tab, this, false);
tab.setCustomView(view);
}
}
}
item_custom_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="#dimen/dp_48"
android:background="#drawable/tab_border"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
</RelativeLayout>
hope this helps
I use :
public class CheckableRelativeLayout extends RelativeLayout implements Checkable {
private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked, };
private boolean mChecked;
public CheckableRelativeLayout(Context context) {
super(context);
}
public CheckableRelativeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CheckableRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void setChecked(boolean checked) {
if (mChecked != checked) {
mChecked = checked;
refreshDrawableState();
}
}
#Override
public boolean isChecked() {
return mChecked;
}
#Override
public void toggle() {
setChecked(!mChecked);
}
#Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
}
based on this and i use it like this :
<com.example.components.CheckableRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/CheckableRelativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/selector_background_navigation_item"
android:orientation="horizontal"
android:padding="10dp"
android:gravity="center_vertical" >
<ImageView
android:id="#+id/navigationDrawerItemImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/navigationDrawerItemTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/navigationDrawerItemImageView"
android:layout_margin="5dp"
android:layout_toRightOf="#+id/navigationDrawerItemImageView"
android:textColor="#drawable/selector_text_navigation_item"
android:textSize="#dimen/text_size_small" />
</com.example.components.CheckableRelativeLayout>
in a list item where selector_background_navigation_item defined like this :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="false" android:state_pressed="false" android:drawable="#color/darkblue"></item>
<item android:state_pressed="true" android:drawable="#color/sirinblue"></item>
<item android:state_checked="true" android:drawable="#color/white"></item>
</selector>
and selector_text_navigation_item defined like this :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="false" android:state_pressed="false" android:color="#color/white"></item>
<item android:state_pressed="true" android:color="#color/lightblue"></item>
<item android:state_checked="true" android:color="#color/lightblue"></item>
</selector>
Now, the problem is that the TextView Selector does not respond to the check events, while the CheckableRelativeLayout does, but both respond correctly to simple presses, whats the best way to fix this? maybe CheckableRelativeLayout missing some super call that handles its children checked state?
adding android:duplicateParentState="true" to the TextView did the trick!
My problem is when my CheckableLinearLayout is checked my draw from the selector can't overlap the unchecked image.
My CheckableLinearLayout
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private boolean mChecked;
private static final String TAG = CheckableLinearLayout.class
.getCanonicalName();
private static final int[] CHECKED_STATE_SET =
{ android.R.attr.state_checked };
public CheckableLinearLayout(final Context context) {
super(context);
setClickable(true);
setLongClickable(true);
}
public CheckableLinearLayout(final Context context,
final AttributeSet attrs) {
super(context, attrs);
setClickable(true);
setLongClickable(true);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public CheckableLinearLayout(final Context context,
final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
setClickable(true);
setLongClickable(true);
}
#Override
public void setChecked(final boolean checked) {
mChecked = checked;
refreshDrawableState();
}
#Override
protected int[] onCreateDrawableState(final int extraSpace) {
final int[] drawableState =
super.onCreateDrawableState(extraSpace + 1);
if (isChecked())
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
return drawableState;
}
#Override
protected void drawableStateChanged() {
super.drawableStateChanged();
final Drawable drawable = getBackground();
if (drawable != null) {
final int[] myDrawableState = getDrawableState();
drawable.setState(myDrawableState);
invalidate();
}
}
#Override
public boolean performClick() {
Toast.makeText(getContext(), "click", Toast.LENGTH_SHORT).show();
if (isChecked()) {
toggle();
return false;
} else
return super.performClick();
}
#Override
public boolean performLongClick() {
toggle();
Toast.makeText(getContext(), "long click", Toast.LENGTH_SHORT).show();
return super.performLongClick();
}
#Override
public boolean isChecked() {
return mChecked;
}
#Override
public void toggle() {
setChecked(!mChecked);
}
#Override
public Parcelable onSaveInstanceState() {
// Force our ancestor class to save its state
final Parcelable superState = super.onSaveInstanceState();
final SavedState savedState = new SavedState(superState);
savedState.checked = isChecked();
return savedState;
}
#Override
public void onRestoreInstanceState(final Parcelable state) {
final SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
setChecked(savedState.checked);
requestLayout();
}
// /////////////
// SavedState //
// /////////////
private static class SavedState extends BaseSavedState {
boolean checked;
#SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR;
static {
CREATOR = new Parcelable.Creator<SavedState>() {
#Override
public SavedState createFromParcel(final Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(final int size) {
return new SavedState[size];
}
};
}
SavedState(final Parcelable superState) {
super(superState);
}
private SavedState(final Parcel in) {
super(in);
checked = (Boolean) in.readValue(null);
}
#Override
public void writeToParcel(final Parcel out, final int flags) {
super.writeToParcel(out, flags);
out.writeValue(checked);
}
#Override
public String toString() {
return TAG + ".SavedState{"
+ Integer.toHexString(System.identityHashCode(this))
+ " checked=" + checked + "}";
}
}
}
My layout.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/topics_preview_main_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/favorites_header_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="2dp"
android:orientation="vertical" >
<TextView
android:id="#+id/favorites_header_title"
style="#style/CardText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:background="#drawable/card"
android:gravity="left"
android:paddingBottom="10dp"
android:paddingLeft="5dp"
android:paddingTop="10dp"
android:text="#string/favorites_header" />
<ui.CheckableLinearLayout
android:id="#+id/favorites_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:background="#drawable/card_selector_w_shadow"
android:clickable="true"
android:longClickable="true"
android:orientation="vertical"
android:paddingBottom="16dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp" >
<TextView
android:id="#+id/favorites_title"
style="#style/CardTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="title" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="4dp"
android:background="#color/C_Favorites_Pink" />
<LinearLayout
android:id="#+id/favorites_description_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="4dp" >
<TextView
android:id="#+id/favorites_description"
style="#style/CardText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:ellipsize="end"
android:maxLines="4"
android:text="Lorem ipsum ..." />
</LinearLayout>
</ui.CheckableLinearLayout>
</LinearLayout>
</FrameLayout>
card_selector_w_shadow-> this draw will call the selector
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape
android:dither="true"
android:shape="rectangle" >
<corners android:radius="2dp" />
<solid android:color="#ccc" />
</shape>
</item>
<item android:bottom="2dp">
<shape
android:dither="true"
android:shape="rectangle" >
<corners android:radius="2dp" />
<solid android:color="#android:color/white" />
<padding
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp" />
</shape>
</item>
<item android:drawable="#drawable/drawable_states"/>
</layer-list>
My drawable_states
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/checked_background"
android:state_checked="true"/>
</selector>
This is what's happening:
This is what I intend:
I think this is because my CheckableLinearLayout only changes the state of the children, so the draw only overlap the children. Any advices?
I have customised progressbar.
HorizontalSlider class which inherits from ProgressBar is:
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ProgressBar;
public class HorizontalSlider extends ProgressBar {
private OnProgressChangeListener listener;
private static final int padding = 2;
private static final int getMin = 11;
public interface OnProgressChangeListener {
void onProgressChanged(View v, int progress);
}
public HorizontalSlider(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, android.R.attr.progressBarStyleHorizontal);
}
public HorizontalSlider(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HorizontalSlider(Context context) {
super(context);
}
public void setOnProgressChangeListener(OnProgressChangeListener l) {
listener = l;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
float x_mouse = event.getX() - padding;
float width = getWidth() - 2 * padding;
int progress = Math.round((float) getMax() * (x_mouse / width));
if (progress < getMin)
progress = getMin;
if (progress > getMax())
progress = getMax();
this.setProgress(progress);
if (listener != null)
listener.onProgressChanged(this, progress);
}
return true;
}
}
UI in xml format is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="100dip"
android:gravity="center_horizontal" >
<com.astro.mania.classes.HorizontalSlider
android:id = "#+id/slider"
android:layout_width = "fill_parent"
android:layout_height= "wrap_content"
android:max="100"
android:layout_centerHorizontal="true"
style="?android:attr/progressBarStyleHorizontal" />
<com.astro.mania.classes.HorizontalSlider
android:id="#+id/progressBar"
android:progressDrawable="#drawable/progressbar"
android:layout_width="fill_parent"
android:layout_height="24dip"
style="?android:attr/progressBarStyleHorizontal"
android:indeterminateOnly="false"
android:max="100"
android:layout_below="#id/slider"
android:layout_marginTop="20dip" />
</RelativeLayout>
Progressbar customised as below:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<gradient
android:startColor="#fffffe"
android:centerColor="#0b131e"
android:centerY="0.75"
android:endColor="#0d1522"
android:angle="270" />
</shape>
</item>
<item android:id="#android:id/secondaryProgress">
<clip>
<shape>
<gradient
android:startColor="#234"
android:centerColor="#234"
android:centerY="0.75"
android:endColor="#a24"
android:angle="270"
/>
</shape>
</clip>
</item>
<item android:id="#android:id/progress">
<bitmap android:src="#drawable/btn_slide_arrow" android:dither="true" />
</item>
</layer-list>
Finally the activity is like this:
public class LensaMania extends Activity {
private HorizontalSlider slider, slider2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.activity_lensamania);
Log.i("LensaMania", "LensaMania activity started...");
setProgressBarVisibility(true);
slider = (HorizontalSlider) this.findViewById(R.id.slider);
slider.setOnProgressChangeListener(changeListener);
slider2 = (HorizontalSlider) this.findViewById(R.id.progressBar);
slider2.setVisibility(View.VISIBLE);
slider2.setMax(100);
slider2.setProgress(11);
slider2.setOnProgressChangeListener(changeListener);
}
private OnProgressChangeListener changeListener = new OnProgressChangeListener() {
public void onProgressChanged(View v, int progress) {
setProgress(progress);
Log.i("Progress is:", "=>" + progress);
}
};
}
When I run the application and slide progreebar, the image is repeated like image below. I want to have just one image and when I slide it to left want to see just one arrow. How to ask progressbar to don't repeat the image?
How could i highlight Gallery selected item without adding the gray border to the image,
without using this.
TypedArray typArray = obtainStyledAttributes(R.styleable.GalleryTheme);
GalItemBg = typArray.getResourceId(
R.styleable.GalleryTheme_android_galleryItemBackground, 3);
typArray.recycle();
and could i add a reflect to the images,
you can define your own view like this:
a custom background:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" android:layout_width="wrap_content">
<stroke android:width="1dp" android:color="#FF000000" />
<solid android:color="#00000000" />
<padding android:left="1dp" android:top="1dp" android:right="1dp"
android:bottom="1dp" />
<corners android:radius="1dp" />
</shape>
</item>
<item android:top="1dp" android:bottom="1dp">
<shape android:shape="rectangle">
<gradient android:startColor="#252525" android:endColor="#252525"
android:angle="270" android:centerColor="#545454" />
<!-- border width and color -->
<stroke android:width="1dp" android:color="#FFDDDDDD" />
</shape>
</item>
</layer-list>
its adapter:
public class AdapterGalleryProducts extends ArrayAdapter<String> {
private int ITEM_WIDTH = 136;
private int ITEM_HEIGHT = 88;
private final int mGalleryItemBackground;
private final Context mContext;
private final float mDensity;
public AdapterGalleryProducts(Context context, int resource,
List<String> items) {
super(context, resource, items);
mContext = context;
TypedArray a = mContext
.obtainStyledAttributes(R.styleable.Gallery1);
mGalleryItemBackground = R.drawable.background02;
a.recycle();
mDensity = mContext.getResources().getDisplayMetrics().density;
boInvProducts = new BoInvProducts(mContext);
}
public void setImageSize(int width, int height) {
ITEM_WIDTH = width;
ITEM_HEIGHT = height;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
convertView = new ImageView(mContext);
imageView = (ImageView) convertView;
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new Gallery.LayoutParams(
(int) (ITEM_WIDTH * mDensity + 0.5f),
(int) (ITEM_HEIGHT * mDensity + 0.5f)));
// The preferred Gallery item background
imageView.setBackgroundResource(mGalleryItemBackground);
imageView.setPadding(5, 5, 5, 5);
} else {
imageView = (ImageView) convertView;
}
Bitmap bitmap = null;
try {
bitmap = getBitmapByFilePath(getItem(position));
} catch (Exception e) {
e.printStackTrace();
}
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
imageView.setAdjustViewBounds(true);
}
return imageView;
}
}
and add animation effects to selected item:
gal.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
gal_onItemClick(parent, v, position, id);
}
});
protected void gal_onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// animate selected image
Animation growAnimation = AnimationUtils.loadAnimation(this,
R.anim.grow_shrink_image);
v.startAnimation(growAnimation);
}
an example of animation (grow_shrink_image.xml):
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200" android:fromXScale="1.0" android:toXScale="1.20"
android:fromYScale="1.0" android:toYScale="1.20" android:pivotX="50%"
android:pivotY="50%" android:interpolator="#android:anim/accelerate_interpolator"
android:fillAfter="false" />
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:startOffset="200" android:duration="200" android:fromXScale="1.0"
android:toXScale="0.8333" android:fromYScale="1.0" android:toYScale="0.8333"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="#android:anim/accelerate_interpolator"
android:fillAfter="false" />
</set>