The application which i am creating has an expandable list view in which i have added the option of swipe to edit and delete.I have added those option but when i run the application it doesn't shows the swipe option even i have tried with another list view but there it works fine.
I have used the swipe option inside the base adapter can anyone tell me why the swipe functionality doesn't works in expandable list view.
Expandablelistview:
public class ExpandableHeightListView extends ListView {
private static final int TOUCH_STATE_NONE = 0;
private static final int TOUCH_STATE_X = 1;
private static final int TOUCH_STATE_Y = 2;
public static final int DIRECTION_LEFT = 1;
public static final int DIRECTION_RIGHT = -1;
private int mDirection = 1;//swipe from right to left by default
private int MAX_Y = 5;
private int MAX_X = 3;
private float mDownX;
private float mDownY;
private int mTouchState;
private int mTouchPosition;
private DaybookSwipeMenuLayout mTouchView;
private OnSwipeListener mOnSwipeListener;
private DaybookSwipeMenuCreator mMenuCreator;
private OnMenuItemClickListener mOnMenuItemClickListener;
private OnMenuStateChangeListener mOnMenuStateChangeListener;
private Interpolator mCloseInterpolator;
private Interpolator mOpenInterpolator;
boolean expanded = false;
public ExpandableHeightListView(Context context) {
super(context);
init();
}
public ExpandableHeightListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ExpandableHeightListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
MAX_X = dp2px(MAX_X);
MAX_Y = dp2px(MAX_Y);
mTouchState = TOUCH_STATE_NONE;
}
public boolean isExpanded() {
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isExpanded()) {
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded) {
this.expanded = expanded;
}
#Override
public void setAdapter(ListAdapter adapter) {
super.setAdapter(new DaybookSwipeMenuAdapter(getContext(), adapter) {
#Override
public void createMenu(DaybookSwipeMenu menu) {
if (mMenuCreator != null) {
mMenuCreator.create(menu);
}
}
#Override
public void onItemClick(DaybookSwipeMenuView view, DaybookSwipeMenu menu,
int index) {
boolean flag = false;
if (mOnMenuItemClickListener != null) {
flag = mOnMenuItemClickListener.onMenuItemClick(
view.getPosition(), menu, index);
}
if (mTouchView != null && !flag) {
mTouchView.smoothCloseMenu();
}
}
});
}
public void setCloseInterpolator(Interpolator interpolator) {
mCloseInterpolator = interpolator;
}
public void setOpenInterpolator(Interpolator interpolator) {
mOpenInterpolator = interpolator;
}
public Interpolator getOpenInterpolator() {
return mOpenInterpolator;
}
public Interpolator getCloseInterpolator() {
return mCloseInterpolator;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//在拦截处处理,在滑动设置了点击事件的地方也能swip,点击时又不能影响原来的点击事件
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mDownX = ev.getX();
mDownY = ev.getY();
boolean handled = super.onInterceptTouchEvent(ev);
mTouchState = TOUCH_STATE_NONE;
mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
//只在空的时候赋值 以免每次触摸都赋值,会有多个open状态
if (view instanceof DaybookSwipeMenuLayout) {
//如果有打开了 就拦截.
if (mTouchView != null && mTouchView.isOpen() && !inRangeOfView(mTouchView.getMenuView(), ev)) {
return true;
}
mTouchView = (DaybookSwipeMenuLayout) view;
mTouchView.setSwipeDirection(mDirection);
}
//如果摸在另外个view
if (mTouchView != null && mTouchView.isOpen() && view != mTouchView) {
handled = true;
}
if (mTouchView != null) {
mTouchView.onSwipe(ev);
}
return handled;
case MotionEvent.ACTION_MOVE:
float dy = Math.abs((ev.getY() - mDownY));
float dx = Math.abs((ev.getX() - mDownX));
if (Math.abs(dy) > MAX_Y || Math.abs(dx) > MAX_X) {
//每次拦截的down都把触摸状态设置成了TOUCH_STATE_NONE 只有返回true才会走onTouchEvent 所以写在这里就够了
if (mTouchState == TOUCH_STATE_NONE) {
if (Math.abs(dy) > MAX_Y) {
mTouchState = TOUCH_STATE_Y;
} else if (dx > MAX_X) {
mTouchState = TOUCH_STATE_X;
if (mOnSwipeListener != null) {
mOnSwipeListener.onSwipeStart(mTouchPosition);
}
}
}
return true;
}
}
return super.onInterceptTouchEvent(ev);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() != MotionEvent.ACTION_DOWN && mTouchView == null)
return super.onTouchEvent(ev);
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
int oldPos = mTouchPosition;
mDownX = ev.getX();
mDownY = ev.getY();
mTouchState = TOUCH_STATE_NONE;
mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
if (mTouchPosition == oldPos && mTouchView != null
&& mTouchView.isOpen()) {
mTouchState = TOUCH_STATE_X;
mTouchView.onSwipe(ev);
return true;
}
View view = getChildAt(mTouchPosition - getFirstVisiblePosition());
if (mTouchView != null && mTouchView.isOpen()) {
mTouchView.smoothCloseMenu();
mTouchView = null;
// return super.onTouchEvent(ev);
// try to cancel the touch event
MotionEvent cancelEvent = MotionEvent.obtain(ev);
cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
onTouchEvent(cancelEvent);
if (mOnMenuStateChangeListener != null) {
mOnMenuStateChangeListener.onMenuClose(oldPos);
}
return true;
}
if (view instanceof DaybookSwipeMenuLayout) {
mTouchView = (DaybookSwipeMenuLayout) view;
mTouchView.setSwipeDirection(mDirection);
}
if (mTouchView != null) {
mTouchView.onSwipe(ev);
}
break;
case MotionEvent.ACTION_MOVE:
//有些可能有header,要减去header再判断
mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()) - getHeaderViewsCount();
//如果滑动了一下没完全展现,就收回去,这时候mTouchView已经赋值,再滑动另外一个不可以swip的view
//会导致mTouchView swip 。 所以要用位置判断是否滑动的是一个view
if (!mTouchView.getSwipEnable() || mTouchPosition != mTouchView.getPosition()) {
break;
}
float dy = Math.abs((ev.getY() - mDownY));
float dx = Math.abs((ev.getX() - mDownX));
if (mTouchState == TOUCH_STATE_X) {
if (mTouchView != null) {
mTouchView.onSwipe(ev);
}
getSelector().setState(new int[]{0});
ev.setAction(MotionEvent.ACTION_CANCEL);
super.onTouchEvent(ev);
return true;
} else if (mTouchState == TOUCH_STATE_NONE) {
if (Math.abs(dy) > MAX_Y) {
mTouchState = TOUCH_STATE_Y;
} else if (dx > MAX_X) {
mTouchState = TOUCH_STATE_X;
if (mOnSwipeListener != null) {
mOnSwipeListener.onSwipeStart(mTouchPosition);
}
}
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_X) {
if (mTouchView != null) {
boolean isBeforeOpen = mTouchView.isOpen();
mTouchView.onSwipe(ev);
boolean isAfterOpen = mTouchView.isOpen();
if (isBeforeOpen != isAfterOpen && mOnMenuStateChangeListener != null) {
if (isAfterOpen) {
mOnMenuStateChangeListener.onMenuOpen(mTouchPosition);
} else {
mOnMenuStateChangeListener.onMenuClose(mTouchPosition);
}
}
if (!isAfterOpen) {
mTouchPosition = -1;
mTouchView = null;
}
}
if (mOnSwipeListener != null) {
mOnSwipeListener.onSwipeEnd(mTouchPosition);
}
ev.setAction(MotionEvent.ACTION_CANCEL);
super.onTouchEvent(ev);
return true;
}
break;
}
return super.onTouchEvent(ev);
}
public void smoothOpenMenu(int position) {
if (position >= getFirstVisiblePosition()
&& position <= getLastVisiblePosition()) {
View view = getChildAt(position - getFirstVisiblePosition());
if (view instanceof DaybookSwipeMenuLayout) {
mTouchPosition = position;
if (mTouchView != null && mTouchView.isOpen()) {
mTouchView.smoothCloseMenu();
}
mTouchView = (DaybookSwipeMenuLayout) view;
mTouchView.setSwipeDirection(mDirection);
mTouchView.smoothOpenMenu();
}
}
}
public void smoothCloseMenu(){
if (mTouchView != null && mTouchView.isOpen()) {
mTouchView.smoothCloseMenu();
}
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getContext().getResources().getDisplayMetrics());
}
public void setMenuCreator(DaybookSwipeMenuCreator menuCreator) {
this.mMenuCreator = menuCreator;
}
public void setOnMenuItemClickListener(
OnMenuItemClickListener onMenuItemClickListener) {
this.mOnMenuItemClickListener = onMenuItemClickListener;
}
public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
this.mOnSwipeListener = onSwipeListener;
}
public void setOnMenuStateChangeListener(OnMenuStateChangeListener onMenuStateChangeListener) {
mOnMenuStateChangeListener = onMenuStateChangeListener;
}
public static interface OnMenuItemClickListener {
boolean onMenuItemClick(int position, DaybookSwipeMenu menu, int index);
}
public static interface OnSwipeListener {
void onSwipeStart(int position);
void onSwipeEnd(int position);
}
public static interface OnMenuStateChangeListener {
void onMenuOpen(int position);
void onMenuClose(int position);
}
public void setSwipeDirection(int direction) {
mDirection = direction;
}
/**
* 判断点击事件是否在某个view内
*
* #param view
* #param ev
* #return
*/
public static boolean inRangeOfView(View view, MotionEvent ev) {
int[] location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y || ev.getRawY() > (y + view.getHeight())) {
return false;
}
return true;
}
BaseAdapter class having the swipe list option:
public class Daybook_adapter extends BaseAdapter {
Context context;
ArrayList<Daybook> entriesdaybook;
ArrayList<Daybooklist> daybooklists;
Daybooklist_adapter adapter;
DatabaseHandler databaseHandler;
LinearLayout emptyy;
double totalamountin=0.0;
ExpandableHeightListView daybookdetailviewlist;
public Daybook_adapter(Context context, ArrayList<Daybook> list) {
this.context = context;
entriesdaybook = list;
}
#Override
public int getCount() {
return entriesdaybook.size();
}
#Override
public Object getItem(int position) {
return entriesdaybook.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup arg2) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.model_daybook, null);
}
Daybook m = entriesdaybook.get(position);
final TextView tv_date = (TextView) convertView.findViewById(R.id.tv_daybook_date);
final TextView tv_cashin = (TextView) convertView.findViewById(R.id.tv_daybook_cashin);
final TextView tv_cashout = (TextView) convertView.findViewById(R.id.tv_daybook_cashout);
final TextView tv_totalamt = (TextView)convertView.findViewById(R.id.daybook_total_amt);
//final String s = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String s = m.getDate();
emptyy = (LinearLayout) convertView.findViewById(R.id.empty);
daybookdetailviewlist = (ExpandableHeightListView) convertView.findViewById(R.id.detaillist_daybook);
String[] spiliter = s.split("-");
String year = spiliter[0];
String month = spiliter[1];
String date = spiliter[2];
if (month.startsWith("01")) {
tv_date.setText(date + "Jan" + year);
} else if (month.startsWith("02")) {
tv_date.setText(date + "Feb" + year);
} else if (month.startsWith("03")) {
tv_date.setText(date + "Mar" + year);
} else if (month.startsWith("04")) {
tv_date.setText(date + "Apr" + year);
} else if (month.startsWith("05")) {
tv_date.setText(date + "May" + year);
} else if (month.startsWith("06")) {
tv_date.setText(date + "Jun" + year);
} else if (month.startsWith("07")) {
tv_date.setText(date + "Jul" + year);
} else if (month.startsWith("08")) {
tv_date.setText(date + "Aug" + year);
} else if (month.startsWith("09")) {
tv_date.setText(date + "Sep" + year);
} else if (month.startsWith("10")) {
tv_date.setText(date + "Oct" + year);
} else if (month.startsWith("11")) {
tv_date.setText(date + "Nov" + year);
} else if (month.startsWith("12")) {
tv_date.setText(date + "Dec" + year);
}
/* if (m.getUsertype().startsWith("singleworker")) {
tv_cashin.setText("\u20B9" + "0");
} else if (m.getUsertype().startsWith("groupworker")) {
tv_cashin.setText("\u20B9" + "0");
}*/
tv_cashin.setText("\u20B9" + m.getCashin());
tv_cashout.setText("\u20B9" + m.getCashout());
double one = Double.parseDouble(m.getCashin());
double two = Double.parseDouble(m.getCashout());
double three = one+two;
tv_totalamt.setText("\u20B9" +String.valueOf(three) );
databaseHandler = new DatabaseHandler(context);
daybooklists = databaseHandler.getAllDaywisedaybookdetails(s);
adapter = new Daybooklist_adapter((Activity) context, daybooklists);
if (adapter != null) {
if (adapter.getCount() > 0) {
emptyy.setVisibility(View.GONE);
daybookdetailviewlist.setAdapter(adapter);
DaybookSwipeMenuCreator creator = new DaybookSwipeMenuCreator() {
#Override
public void create(DaybookSwipeMenu menu) {
// create "open" item
DaybookSwipeMenuItem openItem = new DaybookSwipeMenuItem(
(Activity) context);
// set item background
openItem.setBackground(R.color.colorPrimary);
// set item width
openItem.setWidth(dp2px(90));
// set item title
openItem.setIcon(context.getResources().getDrawable(R.drawable.pencil));
openItem.setTitle("Edit");
// set item title fontsize
openItem.setTitleSize(15);
// set item title font color
openItem.setTitleColor(Color.WHITE);
// add to menu
menu.addMenuItem(openItem);
// create "delete" item
DaybookSwipeMenuItem deleteItem = new DaybookSwipeMenuItem(
(Activity) context);
// set item background
deleteItem.setBackground(R.color.colorPrimaryDark);
// set item width
deleteItem.setWidth(dp2px(90));
// set a icon
deleteItem.setIcon(context.getResources().getDrawable(R.drawable.delete));
deleteItem.setTitle("Delete");
deleteItem.setTitleSize(15);
deleteItem.setTitleColor(Color.WHITE);
// add to menu
menu.addMenuItem(deleteItem);
}
};
daybookdetailviewlist.setMenuCreator(creator);
final ArrayList<Daybooklist> finalListet = daybooklists;
daybookdetailviewlist.setOnMenuItemClickListener(new ExpandableHeightListView.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(final int position, DaybookSwipeMenu menu, int index) {
// Coconuttype item = finalListet.get(position);
// final String farmername = finalListet.get(position).getFarmername();
// final String farmermobno = finalListet.get(position).getFarmermobno();
// final String farmerlocation = finalListet.get(position).getFarmerlocation();
switch (index) {
case 0:
// open
// open(item);
// String farmername = finalListet.get(position).getFarmername();
// String farmermobno = finalListet.get(position).getFarmermobno();
// String farmerlocation =finalListet.get(position).getFarmerlocation();
Log.e("Editclicked", "edt");
// Log.e("farmername", farmername);
// Log.e("farmermobno", farmermobno);
// Log.e("farmerlocation", farmerlocation);
/* Intent k = new Intent(context, FarmerEdit_Activity.class);
k.putExtra("farmername", farmername);
k.putExtra("farmermobno", farmermobno);
k.putExtra("farmerlocation", farmerlocation);
context.startActivity(k);*/
break;
case 1:
// delete
//delete(item);
Log.e("Deleteclicked", "del");
AlertDialog.Builder alert = new AlertDialog.Builder(
context);
alert.setTitle("Delete");
alert.setMessage("Are you sure to delete ");
alert.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//do your work here
finalListet.remove(position);
//databaseHandlerOtherChgs.deleteCoconut(item.getCoconuttype());
// Log.e("farmername", farmername);
// Log.e("farmermobno", farmermobno);
// Log.e("farmerlocation", farmerlocation);
/* databasehandler.deletefarmercontacts(farmername, farmermobno);
databasehandler.deletedaybookdetails(farmername, farmermobno);
databasehandler.deletefarmeradvance(farmername, farmermobno);
databasehandler.deletefarmerbillbookdetails(farmername, farmermobno);
databasehandler.deletefarmertradedetails(farmername, farmermobno);
fadapter.notifyDataSetChanged();
Intent k = getIntent();
finish();
startActivity(k);*/
}
});
alert.setNegativeButton(context.getResources().getString(R.string.no), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert.show();
/* finalListet.remove(position);
databaseHandlerOtherChgs.deleteCoconut(item.getCoconuttype());
adapter.notifyDataSetChanged();
Intent k = getIntent();
finish();
startActivity(k);*/
break;
}
return false;
}
});
// set SwipeListener
daybookdetailviewlist.setOnSwipeListener(new ExpandableHeightListView.OnSwipeListener() {
#Override
public void onSwipeStart(int position) {
// swipe start
}
#Override
public void onSwipeEnd(int position) {
// swipe end
}
});
// set MenuStateChangeListener
daybookdetailviewlist.setOnMenuStateChangeListener(new ExpandableHeightListView.OnMenuStateChangeListener() {
#Override
public void onMenuOpen(int position) {
}
#Override
public void onMenuClose(int position) {
}
});
}
}else {
daybookdetailviewlist.setEmptyView(emptyy);
}
daybookdetailviewlist.setExpanded(true);
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//todo disable the comments for farmer individual transaction
}
});
return convertView;
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
context.getResources().getDisplayMetrics());
}
public void setTransactionList(ArrayList<Daybook> newList) {
entriesdaybook = newList;
notifyDataSetChanged();
}
}
I m posting code here , i hope it helps u
activity_main.xml :
<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">
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:focusable="false"
android:text="Click this:notify data set changed and re-open the opened menu" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/btn">
<com.allen.expandablelistview.SwipeMenuExpandableListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="500dp"
android:layout_below="#id/btn"
android:groupIndicator="#null" />
</FrameLayout>
</RelativeLayout>
MainActivity.java :
public class MainActivity extends AppCompatActivity {
private List<ApplicationInfo> mAppList;
private AppAdapter mAdapter;
private SwipeMenuExpandableListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAppList = getPackageManager().getInstalledApplications(0);
findViewById(R.id.btn).setOnClickListener(l);
// 1. Create View
listView = (SwipeMenuExpandableListView) findViewById(R.id.listView);
if (getIntent().getBooleanExtra("stick_mode", false)) {
// 2. Set where does the menu item stick with
/**
* STICK_TO_ITEM_RIGHT_SIDE: Stick with item right side, when swipe,
* it moves from outside of screen .
**/
/**
* STICK_TO_SCREEN: stick with the screen, it was covered and don't
* move ,item moves then menu show.
**/
listView.setmMenuStickTo(SwipeMenuListView.STICK_TO_SCREEN);
}
// 3. Create Adapter and set. It controls data,
// item view,clickable ,swipable ...
mAdapter = new AppAdapter();
listView.setAdapter(mAdapter);
// 4. Set OnItemLongClickListener
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
int itemType = ExpandableListView.getPackedPositionType(id);
int childPosition, groupPosition;
if (itemType == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
childPosition = ExpandableListView.getPackedPositionChild(id);
groupPosition = ExpandableListView.getPackedPositionGroup(id);
// do your per-item callback here
Toast.makeText(MainActivity.this,
"long click on group " + groupPosition + " child " + childPosition, Toast.LENGTH_SHORT)
.show();
return true; // true if we consumed the click, false if not
} else if (itemType == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
groupPosition = ExpandableListView.getPackedPositionGroup(id);
// do your per-group callback here
Toast.makeText(MainActivity.this, "long click on group " + groupPosition,
Toast.LENGTH_SHORT).show();
return true; // true if we consumed the click, false if not
} else {
// null item; we don't consume the click
return false;
}
}
});
// 5.Set OnGroupClickListener
listView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Toast.makeText(MainActivity.this, "group " + groupPosition + " clicked", Toast.LENGTH_SHORT)
.show();
return false;
}
});
// 6.Set OnChildClickListener
listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Toast.makeText(MainActivity.this,
"group " + groupPosition + " child " + childPosition + " clicked", Toast.LENGTH_SHORT).show();
return false;
}
});
// 7. Create and set a SwipeMenuExpandableCreator
// define the group and child creator function
SwipeMenuExpandableCreator creator = new SwipeMenuExpandableCreator() {
#Override
public void createGroup(SwipeMenu menu) {
// Create different menus depending on the view type
switch (menu.getViewType()) {
case 0:
createMenu1(menu);
break;
case 1:
createMenu2(menu);
break;
case 2:
createMenu3(menu);
break;
}
}
#Override
public void createChild(SwipeMenu menu) {
// Create different menus depending on the view type
switch (menu.getViewType()) {
case 0:
createMenu1(menu);
break;
case 1:
createMenu2(menu);
break;
case 2:
createMenu3(menu);
break;
}
}
private void createMenu1(SwipeMenu menu) {
SwipeMenuItem item1 = new SwipeMenuItem(getApplicationContext());
item1.setBackground(new ColorDrawable(Color.rgb(0xE5, 0x18, 0x5E)));
item1.setWidth(dp2px(90));
item1.setIcon(R.drawable.ic_action_favorite);
menu.addMenuItem(item1);
SwipeMenuItem item2 = new SwipeMenuItem(getApplicationContext());
item2.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9, 0xCE)));
item2.setWidth(dp2px(90));
item2.setIcon(R.drawable.ic_action_good);
menu.addMenuItem(item2);
}
private void createMenu2(SwipeMenu menu) {
SwipeMenuItem item1 = new SwipeMenuItem(getApplicationContext());
item1.setBackground(new ColorDrawable(Color.rgb(0xE5, 0xE0, 0x3F)));
item1.setWidth(dp2px(90));
item1.setIcon(R.drawable.ic_action_important);
menu.addMenuItem(item1);
SwipeMenuItem item2 = new SwipeMenuItem(getApplicationContext());
item2.setBackground(new ColorDrawable(Color.rgb(0xF9, 0x3F, 0x25)));
item2.setWidth(dp2px(90));
item2.setIcon(R.drawable.ic_action_discard);
menu.addMenuItem(item2);
}
private void createMenu3(SwipeMenu menu) {
SwipeMenuItem item1 = new SwipeMenuItem(getApplicationContext());
item1.setBackground(new ColorDrawable(Color.rgb(0x30, 0xB1, 0xF5)));
item1.setWidth(dp2px(90));
item1.setIcon(R.drawable.ic_action_about);
menu.addMenuItem(item1);
SwipeMenuItem item2 = new SwipeMenuItem(getApplicationContext());
item2.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9, 0xCE)));
item2.setWidth(dp2px(90));
item2.setIcon(R.drawable.ic_action_share);
menu.addMenuItem(item2);
}
};
listView.setMenuCreator(creator);
// 8. Set OnMenuItemClickListener
listView.setOnMenuItemClickListener(new SwipeMenuExpandableListView.OnMenuItemClickListenerForExpandable() {
#Override
public boolean onMenuItemClick(int groupPostion, int childPostion, SwipeMenu menu, int index) {
ApplicationInfo item = mAppList.get(groupPostion);
// childPostion == -1991 means it was the group's swipe menu was
// clicked
String s = "Group " + groupPostion;
if (childPostion != SwipeMenuExpandableListAdapter.GROUP_INDEX) {
s += " , child " + childPostion;
}
s += " , menu index:" + index + " was clicked";
switch (index) {
case 0:
// open
break;
case 1:
// delete
// delete(item);
mAppList.remove(groupPostion);
mAdapter.notifyDataSetChanged();
break;
}
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
return false;
}
});
}
public void btnClick(View view) {
}
/**
* Basically, it's the same as BaseExpandableListAdapter. But added controls
* to every item's swipability
*
* #author yuchentang
* #see android.widget.BaseExpandableListAdapter
*/
class AppAdapter extends BaseSwipeMenuExpandableListAdapter {
/**
* Whether this group item swipable
*
* #param groupPosition
* #return
* #see com.allen.expandablelistview.BaseSwipeMenuExpandableListAdapter#isGroupSwipable(int)
*/
#Override
public boolean isGroupSwipable(int groupPosition) {
return true;
}
/**
* Whether this child item swipable
*
* #param groupPosition
* #param childPosition
* #return
* #see com.allen.expandablelistview.BaseSwipeMenuExpandableListAdapter#isChildSwipable(int,
* int)
*/
#Override
public boolean isChildSwipable(int groupPosition, int childPosition) {
if (childPosition == 0)
return false;
return true;
}
#Override
public int getChildType(int groupPosition, int childPosition) {
return childPosition % 3;
}
#Override
public int getChildTypeCount() {
return 3;
}
#Override
public int getGroupType(int groupPosition) {
return groupPosition % 3;
}
#Override
public int getGroupTypeCount() {
return 3;
}
class ViewHolder {
ImageView iv_icon;
TextView tv_name;
public ViewHolder(View view) {
iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
tv_name = (TextView) view.findViewById(R.id.tv_name);
view.setTag(this);
}
}
#Override
public int getGroupCount() {
return mAppList.size();
}
#Override
public int getChildrenCount(int groupPosition) {
return 3;
}
#Override
public Object getGroup(int groupPosition) {
return mAppList.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return "The " + childPosition + "'th child in " + groupPosition + "'th group.";
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public ContentViewWrapper getGroupViewAndReUsable(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
boolean reUseable = true;
if (convertView == null) {
convertView = View.inflate(getApplicationContext(), R.layout.item_list_app, null);
convertView.setTag(new ViewHolder(convertView));
reUseable = false;
}
ViewHolder holder = (ViewHolder) convertView.getTag();
ApplicationInfo item = (ApplicationInfo) getGroup(groupPosition);
holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager()));
holder.tv_name.setText(item.loadLabel(getPackageManager()));
return new ContentViewWrapper(convertView, reUseable);
}
#Override
public ContentViewWrapper getChildViewAndReUsable(int groupPosition, int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
boolean reUseable = true;
if (convertView == null) {
convertView = View.inflate(getApplicationContext(), R.layout.item_list_app, null);
convertView.setTag(new ViewHolder(convertView));
reUseable = false;
}
ViewHolder holder = (ViewHolder) convertView.getTag();
if (null == holder) {
holder = new ViewHolder(convertView);
}
ApplicationInfo item = (ApplicationInfo) getGroup(groupPosition);
convertView.setBackgroundColor(Color.GRAY);
holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager()));
holder.tv_name.setText("this is child");
return new ContentViewWrapper(convertView, reUseable);
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
View.OnClickListener l = new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mAdapter.notifyDataSetChanged(true);
}
};
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
}
Hereby, i am attaching screenshot
Try this Code,
https://github.com/tycallen/SwipeMenu-Expandable-ListView.
Download and Import to Android studio.
Related
I tried setting background color in my xml file in custom scroll view but it showed error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Alert dialog color is white i want slightly transparent!
having background color of the alert dialog to be #24000000(slightly transparent) in this small library taken from here:
https://github.com/wangjiegulu/WheelView
What changes are needed to accomplish that?
Custom scroll view:
/**
* Author: wangjie
* Email: tiantian.china.2#gmail.com
* Date: 7/1/14.
*/
public class WheelView extends ScrollView {
public static final String TAG = WheelView.class.getSimpleName();
public static class OnWheelViewListener {
public void onSelected(int selectedIndex, String item) {
}
}
private Context context;
// private ScrollView scrollView;
private LinearLayout views;
public WheelView(Context context) {
super(context);
init(context);
}
public WheelView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public WheelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
// String[] items;
List<String> items;
private List<String> getItems() {
return items;
}
public void setItems(List<String> list) {
if (null == items) {
items = new ArrayList<String>();
}
items.clear();
items.addAll(list);
// 前面和后面补全
for (int i = 0; i < offset; i++) {
items.add(0, "");
items.add("");
}
initData();
}
public static final int OFF_SET_DEFAULT = 1;
int offset = OFF_SET_DEFAULT; // 偏移量(需要在最前面和最后面补全)
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
int displayItemCount; // 每页显示的数量
int selectedIndex = 1;
private void init(Context context) {
this.context = context;
// scrollView = ((ScrollView)this.getParent());
// Log.d(TAG, "scrollview: " + scrollView);
Log.d(TAG, "parent: " + this.getParent());
// this.setOrientation(VERTICAL);
this.setVerticalScrollBarEnabled(false);
views = new LinearLayout(context);
views.setOrientation(LinearLayout.VERTICAL);
this.addView(views);
scrollerTask = new Runnable() {
public void run() {
int newY = getScrollY();
if (initialY - newY == 0) { // stopped
final int remainder = initialY % itemHeight;
final int divided = initialY / itemHeight;
// Log.d(TAG, "initialY: " + initialY);
// Log.d(TAG, "remainder: " + remainder + ", divided: " + divided);
if (remainder == 0) {
selectedIndex = divided + offset;
onSeletedCallBack();
} else {
if (remainder > itemHeight / 2) {
WheelView.this.post(new Runnable() {
#Override
public void run() {
WheelView.this.smoothScrollTo(0, initialY - remainder + itemHeight);
selectedIndex = divided + offset + 1;
onSeletedCallBack();
}
});
} else {
WheelView.this.post(new Runnable() {
#Override
public void run() {
WheelView.this.smoothScrollTo(0, initialY - remainder);
selectedIndex = divided + offset;
onSeletedCallBack();
}
});
}
}
} else {
initialY = getScrollY();
WheelView.this.postDelayed(scrollerTask, newCheck);
}
}
};
}
int initialY;
Runnable scrollerTask;
int newCheck = 50;
public void startScrollerTask() {
initialY = getScrollY();
this.postDelayed(scrollerTask, newCheck);
}
private void initData() {
displayItemCount = offset * 2 + 1;
for (String item : items) {
views.addView(createView(item));
}
refreshItemView(0);
}
int itemHeight = 0;
private TextView createView(String item) {
TextView tv = new TextView(context);
tv.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
tv.setSingleLine(true);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
tv.setText(item);
tv.setGravity(Gravity.CENTER);
int padding = dip2px(15);
tv.setPadding(padding, padding, padding, padding);
if (0 == itemHeight) {
itemHeight = getViewMeasuredHeight(tv);
Log.d(TAG, "itemHeight: " + itemHeight);
views.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight * displayItemCount));
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.getLayoutParams();
this.setLayoutParams(new LinearLayout.LayoutParams(lp.width, itemHeight * displayItemCount));
}
return tv;
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
// Log.d(TAG, "l: " + l + ", t: " + t + ", oldl: " + oldl + ", oldt: " + oldt);
// try {
// Field field = ScrollView.class.getDeclaredField("mScroller");
// field.setAccessible(true);
// OverScroller mScroller = (OverScroller) field.get(this);
//
//
// if(mScroller.isFinished()){
// Log.d(TAG, "isFinished...");
// }
//
// } catch (Exception e) {
// e.printStackTrace();
// }
refreshItemView(t);
if (t > oldt) {
// Log.d(TAG, "向下滚动");
scrollDirection = SCROLL_DIRECTION_DOWN;
} else {
// Log.d(TAG, "向上滚动");
scrollDirection = SCROLL_DIRECTION_UP;
}
}
private void refreshItemView(int y) {
int position = y / itemHeight + offset;
int remainder = y % itemHeight;
int divided = y / itemHeight;
if (remainder == 0) {
position = divided + offset;
} else {
if (remainder > itemHeight / 2) {
position = divided + offset + 1;
}
// if(remainder > itemHeight / 2){
// if(scrollDirection == SCROLL_DIRECTION_DOWN){
// position = divided + offset;
// Log.d(TAG, ">down...position: " + position);
// }else if(scrollDirection == SCROLL_DIRECTION_UP){
// position = divided + offset + 1;
// Log.d(TAG, ">up...position: " + position);
// }
// }else{
//// position = y / itemHeight + offset;
// if(scrollDirection == SCROLL_DIRECTION_DOWN){
// position = divided + offset;
// Log.d(TAG, "<down...position: " + position);
// }else if(scrollDirection == SCROLL_DIRECTION_UP){
// position = divided + offset + 1;
// Log.d(TAG, "<up...position: " + position);
// }
// }
// }
// if(scrollDirection == SCROLL_DIRECTION_DOWN){
// position = divided + offset;
// }else if(scrollDirection == SCROLL_DIRECTION_UP){
// position = divided + offset + 1;
}
int childSize = views.getChildCount();
for (int i = 0; i < childSize; i++) {
TextView itemView = (TextView) views.getChildAt(i);
if (null == itemView) {
return;
}
if (position == i) {
itemView.setTextColor(Color.parseColor("#0288ce"));
} else {
itemView.setTextColor(Color.parseColor("#bbbbbb"));
}
}
}
/**
* 获取选中区域的边界
*/
int[] selectedAreaBorder;
private int[] obtainSelectedAreaBorder() {
if (null == selectedAreaBorder) {
selectedAreaBorder = new int[2];
selectedAreaBorder[0] = itemHeight * offset;
selectedAreaBorder[1] = itemHeight * (offset + 1);
}
return selectedAreaBorder;
}
private int scrollDirection = -1;
private static final int SCROLL_DIRECTION_UP = 0;
private static final int SCROLL_DIRECTION_DOWN = 1;
Paint paint;
int viewWidth;
#Override
public void setBackgroundDrawable(Drawable background) {
if (viewWidth == 0) {
viewWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();
Log.d(TAG, "viewWidth: " + viewWidth);
}
if (null == paint) {
paint = new Paint();
paint.setColor(Color.parseColor("#83cde6"));
paint.setStrokeWidth(dip2px(1f));
}
background = new Drawable() {
#Override
public void draw(Canvas canvas) {
canvas.drawLine(viewWidth * 1 / 6, obtainSelectedAreaBorder()[0], viewWidth * 5 / 6, obtainSelectedAreaBorder()[0], paint);
canvas.drawLine(viewWidth * 1 / 6, obtainSelectedAreaBorder()[1], viewWidth * 5 / 6, obtainSelectedAreaBorder()[1], paint);
}
#Override
public void setAlpha(int alpha) {
}
#Override
public void setColorFilter(ColorFilter cf) {
}
#Override
public int getOpacity() {
return 0;
}
};
super.setBackgroundDrawable(background);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.d(TAG, "w: " + w + ", h: " + h + ", oldw: " + oldw + ", oldh: " + oldh);
viewWidth = w;
setBackgroundDrawable(null);
}
/**
* 选中回调
*/
private void onSeletedCallBack() {
if (null != onWheelViewListener) {
onWheelViewListener.onSelected(selectedIndex, items.get(selectedIndex));
}
}
public void setSeletion(int position) {
final int p = position;
selectedIndex = p + offset;
this.post(new Runnable() {
#Override
public void run() {
WheelView.this.smoothScrollTo(0, p * itemHeight);
}
});
}
public String getSeletedItem() {
return items.get(selectedIndex);
}
public int getSeletedIndex() {
return selectedIndex - offset;
}
#Override
public void fling(int velocityY) {
super.fling(velocityY / 3);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
startScrollerTask();
}
return super.onTouchEvent(ev);
}
private OnWheelViewListener onWheelViewListener;
public OnWheelViewListener getOnWheelViewListener() {
return onWheelViewListener;
}
public void setOnWheelViewListener(OnWheelViewListener onWheelViewListener) {
this.onWheelViewListener = onWheelViewListener;
}
private int dip2px(float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
private int getViewMeasuredHeight(View view) {
int width = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int expandSpec = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
view.measure(width, expandSpec);
return view.getMeasuredHeight();
}
}
Main activity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = MainActivity.class.getSimpleName();
private static final String[] PLANETS = new String[]{"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Uranus", "Neptune", "Pluto"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WheelView wva = (WheelView) findViewById(R.id.main_wv);
wva.setOffset(1);
wva.setItems(Arrays.asList(PLANETS));
wva.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
#Override
public void onSelected(int selectedIndex, String item) {
Log.d(TAG, "selectedIndex: " + selectedIndex + ", item: " + item);
}
});
findViewById(R.id.main_show_dialog_btn).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_show_dialog_btn:
View outerView = LayoutInflater.from(this).inflate(R.layout.wheel_view, null);
WheelView wv = (WheelView) outerView.findViewById(R.id.wheel_view_wv);
wv.setOffset(2);
wv.setItems(Arrays.asList(PLANETS));
wv.setSeletion(3);
wv.setOnWheelViewListener(new WheelView.OnWheelViewListener() {
#Override
public void onSelected(int selectedIndex, String item) {
Log.d(TAG, "[Dialog]selectedIndex: " + selectedIndex + ", item: " + item);
}
});
new AlertDialog.Builder(this)
.setTitle("WheelView in Dialog")
.setView(outerView)
.setPositiveButton("OK", null)
.show();
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I'm trying to use ViewDragHelp to implement draggable panel but the problem is the hidden part of panel isn't shown. Picture what i meant
Here is my code . SlidePanel is the draggable panel and the "white_pane" is the partially hidden panel (i set the bttom margin as -280dp)
SlidePanel.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center|bottom"
>
<RelativeLayout
android:id="#+id/name_pane"
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="#drawable/name_layout"
>
<TextView
android:id="#+id/name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
android:textSize="20sp"
android:fontFamily="sans-serif-medium"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
>
</TextView>
</RelativeLayout>
<RelativeLayout
android:id="#+id/white_pane"
android:layout_width="match_parent"
android:layout_height="280dp"
android:layout_marginBottom="-200dp"
android:background="#F0F2F4">
</RelativeLayout>
</LinearLayout>
SlidePanel.java
public class SlidePanel extends LinearLayout {
private ViewDragHelper mDragHelper;
protected ViewGroup whitePanel;
protected ViewGroup namePanel;
protected TextView nameText;
private Status status;
private Animation show , hide;
MapsActivity mapAct;
LayoutInflater mInflater;
private int mDraggingBorder;
private int mVerticalRange;
private boolean mIsOpen;
private final double AUTO_OPEN_SPEED_LIMIT = 800.0;
private int mDraggingState = 0;
public SlidePanel(Context context) {
super(context);
mInflater = LayoutInflater.from(context);
init();
}
public SlidePanel(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mInflater = LayoutInflater.from(context);
init();
}
public SlidePanel(Context context, AttributeSet attrs) {
super(context, attrs);
mInflater = LayoutInflater.from(context);
init();
}
public void init()
{
mInflater.inflate(R.layout.slide_panel, this, true);
//hiddenPanel = (ViewGroup)mapAct.findViewById(R.id.hidden_panel);
whitePanel = (ViewGroup)findViewById(R.id.white_pane);
namePanel = (ViewGroup)findViewById(R.id.name_pane);
nameText = (TextView)findViewById(R.id.name_text);
//slidingLayout = (SlidingUpPanelLayout)mapAct.findViewById(R.id.sliding_layout);
status = Status.HIDDEN;
this.setVisibility(View.INVISIBLE);
mDragHelper = ViewDragHelper.create(this,1.0f , new DragHelperCallback());
}
public void initAnim(MapsActivity mapAct){
this.mapAct = mapAct;
show = AnimationUtils.loadAnimation(mapAct, R.anim.show);
hide = AnimationUtils.loadAnimation(mapAct, R.anim.hide);
}
public void show(ParseObject area){
if(status.equals(Status.HIDDEN)){
startAnimation(show);
setVisibility(View.VISIBLE);
status = Status.SHOW;
//hashMarker.get(marker.getId())
}
nameText.setText(area.getString("name"));
}
public void hide(){
if(status.equals(Status.SHOW)){
startAnimation(hide);
setVisibility(View.INVISIBLE);
status = Status.HIDDEN;
}
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (isTarget(event) /*&& mDragHelper.shouldInterceptTouchEvent(event)*/) {
//Log.e("intercept", "intercept true");
return true;
} else {
//Log.e("intercept", "intercept false");
return false;
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (isTarget(event) || isMoving()) {
mDragHelper.processTouchEvent(event);
//Log.e("touch", "touch true");
return true;
} else {
//Log.e("touch", "touch false");
return super.onTouchEvent(event);
}
}
private boolean isTarget(MotionEvent event) {
int[] location = new int[2];
whitePanel.getLocationOnScreen(location);
int upperLimit = location[1] + whitePanel.getMeasuredHeight();
int lowerLimit = location[1] - namePanel.getMeasuredHeight();
int y = (int) event.getRawY();
//Log.e("touch", "upper target: " + upperLimit +" & lower target: "+ lowerLimit);
//Log.e("touch", "touch at: " + y);
return (y > lowerLimit && y < upperLimit);
}
private class DragHelperCallback extends ViewDragHelper.Callback {
#Override
public boolean tryCaptureView(View view, int pointerId) {
//Log.e("capture", "Capture white is " + (view.getId() == R.id.white_pane) + " but it capture " + view.getId());
//return (view.getId() == R.id.white_pane);
return true;
}
#Override
public void onViewDragStateChanged(int state) {
if (state == mDraggingState) { // no change
return;
}
if ((mDraggingState == ViewDragHelper.STATE_DRAGGING || mDraggingState == ViewDragHelper.STATE_SETTLING) &&
state == ViewDragHelper.STATE_IDLE) {
// the view stopped from moving.
if (mDraggingBorder == 0) {
onStopDraggingToClosed();
} else if (mDraggingBorder == mVerticalRange) {
mIsOpen = true;
}
}
if (state == ViewDragHelper.STATE_DRAGGING) {
onStartDragging();
}
mDraggingState = state;
Log.e("Drag" , "State changed : " + state);
}
#Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
mDraggingBorder = top;
}
public int getViewVerticalDragRange(View child) {
return mVerticalRange;
}
#Override
public int clampViewPositionVertical(View child, int top, int dy) {
final int topBound = getPaddingTop();
final int bottomBound = mVerticalRange;
Log.e("Drag" , "clamp at topBound = " + topBound + " and bottom = " + bottomBound + " and top= " + top);
//return Math.min(Math.max(top, topBound), bottomBound);
//status = top>0? Status.SLIDE_DOWN:Status.SLIDE_UP;
return Math.min(top, bottomBound);
}
#Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
final float rangeToCheck = mVerticalRange;
Log.e("Drag" , "Released. rangeToCheck: " + rangeToCheck + " and mDraggingBorder: " + mDraggingBorder);
if (mDraggingBorder == 0) {
mIsOpen = false;
return;
}
if (mDraggingBorder == rangeToCheck) {
mIsOpen = true;
return;
}
Log.e("Drag" , "Released. y velocity = " + yvel);
boolean settleToOpen = false;
if (yvel > AUTO_OPEN_SPEED_LIMIT) { // speed has priority over position
settleToOpen = true;
Log.e("drag" , "FUCKING OVER SPEED");
} else if (yvel < -AUTO_OPEN_SPEED_LIMIT) {
settleToOpen = true;
} else if (Math.abs(mDraggingBorder )> rangeToCheck / 2) {
settleToOpen = true;
} else if (Math.abs(mDraggingBorder) < rangeToCheck / 2) {
settleToOpen = false;
}
int settleDestY = settleToOpen ? mVerticalRange : 0;
if(yvel > AUTO_OPEN_SPEED_LIMIT) settleDestY = 0;
Log.e("drag" , "settle Dest Y : " + settleDestY );
if(mDraggingBorder < 0)settleDestY = settleDestY * -1;
if(mDragHelper.settleCapturedViewAt(0, settleDestY)) {
ViewCompat.postInvalidateOnAnimation(SlidePanel.this);
}
}
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//mVerticalRange = (int) (h * 0.66);
int inPixel = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 110, getResources().getDisplayMetrics());
mVerticalRange = h - inPixel;
//super.onSizeChanged(w, h, oldw, oldh);
}
private void onStopDraggingToClosed() {
// To be implemented
Log.e("Drag" , "On stop drag to close");
}
private void onStartDragging() {
Log.e("Drag" , "On start drag");
}
#Override
public void computeScroll() { // needed for automatic settling.
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
public boolean isMoving() {
return (mDraggingState == ViewDragHelper.STATE_DRAGGING ||
mDraggingState == ViewDragHelper.STATE_SETTLING);
}
public boolean isOpen() {
if(status == Status.SHOW){
return false;
}else{
return mIsOpen;
}
}
}
I have to build animation like This.
Sorry I don't have too much reputation to upload image. you can find gif file from the above link.
I have done all this and it works fine on KitKat and LollyPop only but not on the other API version. I am using this library. Can any one please figure out the actual problem
Here is my code. Thanks in advance
public abstract class AbstractSlideExpandableListAdapter extends WrapperListAdapterImpl
{
private View lastOpnUpperView = null;
ArrayList<View> upperViewsList = new ArrayList<View>();
ArrayList<View> lowerViewsList = new ArrayList<View>();
ArrayList<View> circleViewsList = new ArrayList<View>();
private View lastOpen = null;
private int lastOpenPosition = -1;
private int lastOpenItemIndex = 0;
private int animationDuration = 800;
private BitSet openItems = new BitSet();
private final SparseIntArray viewHeights = new SparseIntArray(10);
private ViewGroup parent;
public AbstractSlideExpandableListAdapter(ListAdapter wrapped)
{
super(wrapped);
lastOpenPosition = 0;
openItems.set(lastOpenPosition, true);
}
private OnItemExpandCollapseListener expandCollapseListener;
public void setItemExpandCollapseListener(OnItemExpandCollapseListener listener)
{
expandCollapseListener = listener;
}
public void removeItemExpandCollapseListener()
{
expandCollapseListener = null;
}
public interface OnItemExpandCollapseListener
{
public void onExpand(View itemView, int position);
public void onCollapse(View itemView, int position);
}
private void notifiyExpandCollapseListener(int type, View view, int position)
{
if (expandCollapseListener != null)
{
if (type == ExpandCollapseAnimation.EXPAND)
{
expandCollapseListener.onExpand(view, position);
}
else if (type == ExpandCollapseAnimation.COLLAPSE)
{
expandCollapseListener.onCollapse(view, position);
}
}
}
#Override
public View getView(int position, View view, ViewGroup viewGroup)
{
this.parent = viewGroup;
view = wrapped.getView(position, view, viewGroup);
enableFor(view, position);
return view;
}
public abstract View getExpandToggleButton(View parent);
public abstract View getExpandableView(View parent);
// upperView to expand animation for sequeeze
public abstract View getUpperView(View upperView);
// Lower view to expand and collapse
public abstract View getLowerView(View upperView);
// Get the circle view to hide and show
public abstract View getCircleView(View circleView);
/**
* Gets the duration of the collapse animation in ms. Default is 330ms. Override this method to change the default.
*
* #return the duration of the anim in ms
*/
public int getAnimationDuration()
{
return animationDuration;
}
/**
* Set's the Animation duration for the Expandable animation
*
* #param duration
* The duration as an integer in MS (duration > 0)
* #exception IllegalArgumentException
* if parameter is less than zero
*/
public void setAnimationDuration(int duration)
{
if (duration < 0)
{
throw new IllegalArgumentException("Duration is less than zero");
}
animationDuration = duration;
}
/**
* Check's if any position is currently Expanded To collapse the open item #see collapseLastOpen
*
* #return boolean True if there is currently an item expanded, otherwise false
*/
public boolean isAnyItemExpanded()
{
return (lastOpenPosition != -1) ? true : false;
}
public void enableFor(View parent, int position)
{
View more = getExpandToggleButton(parent);
View itemToolbar = getExpandableView(parent);
View upperView = getUpperView(parent);
View circleView = getCircleView(parent);
View lowerView = getLowerView(parent);
itemToolbar.measure(parent.getWidth(), parent.getHeight());
upperViewsList.add(upperView);
circleViewsList.add(circleView);
lowerViewsList.add(lowerView);
if (position == 0)
{
// lastopenUpperViewTemporary = upperView;
lastOpnUpperView = upperView;
upperView.setVisibility(View.GONE);
lowerView.setVisibility(View.GONE);
}
enableFor(more, upperView, itemToolbar, position);
itemToolbar.requestLayout();
}
private void animateListExpand(final View button, final View target, final int position)
{
target.setAnimation(null);
int type;
if (target.getVisibility() == View.VISIBLE)
{
type = ExpandCollapseAnimation.COLLAPSE;
}
else
{
type = ExpandCollapseAnimation.EXPAND;
}
// remember the state
if (type == ExpandCollapseAnimation.EXPAND)
{
openItems.set(position, true);
}
else
{
openItems.set(position, false);
}
// check if we need to collapse a different view
if (type == ExpandCollapseAnimation.EXPAND)
{
if (lastOpenPosition != -1 && lastOpenPosition != position)
{
if (lastOpen != null)
{
animateWithUpperView(lastOpen, ExpandCollapseAnimation.COLLAPSE, position);
// animateView(lastOpen, ExpandCollapseAnimation.COLLAPSE);
notifiyExpandCollapseListener(ExpandCollapseAnimation.COLLAPSE, lastOpen, lastOpenPosition);
}
openItems.set(lastOpenPosition, false);
}
lastOpen = target;
lastOpenPosition = position;
}
else if (lastOpenPosition == position)
{
lastOpenPosition = -1;
}
// animateView(target, type);
// Expand the view which was collapse
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
target.startAnimation(anim);
this.notifiyExpandCollapseListener(type, target, position);
// }
}
private void enableFor(final View button, final View upperView, final View target, final int position)
{
// lastopenUpperViewTemporary = upperView;
if (target == lastOpen && position != lastOpenPosition)
{
// lastOpen is recycled, so its reference is false
lastOpen = null;
}
if (position == lastOpenPosition)
{
// re reference to the last view
// so when can animate it when collapsed
// lastOpen = target;
lastOpen = target;
lastOpnUpperView = upperView;
}
int height = viewHeights.get(position, -1);
if (height == -1)
{
viewHeights.put(position, target.getMeasuredHeight());
updateExpandable(target, position);
}
else
{
updateExpandable(target, position);
}
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(final View view)
{
System.out.println("Position: " + position);
if (lastOpenPosition == position)
{
return;
}
System.out.println("Upper View: " + upperView);
Animation anim = new ExpandCollapseUpperViewAnimation(upperViewsList.get(position), ExpandCollapseUpperViewAnimation.COLLAPSE);
anim.setDuration(800);
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
circleViewsList.get(position).setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation)
{
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation)
{
// TODO Auto-generated method stub
// upperViewsList.get(position).setVisibility(View.VISIBLE);
animateListExpand(button, target, position);
}
});
upperViewsList.get(position).startAnimation(anim);
// Lower animation
Animation lowerAnim = new ExpandCollapseUpperViewAnimation(lowerViewsList.get(position), ExpandCollapseUpperViewAnimation.COLLAPSE);
lowerAnim.setDuration(800);
lowerViewsList.get(position).startAnimation(lowerAnim);
}
});
}
private void updateExpandable(View target, int position)
{
final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) target.getLayoutParams();
if (openItems.get(position))
{
target.setVisibility(View.VISIBLE);
params.bottomMargin = 0;
}
else
{
target.setVisibility(View.GONE);
params.bottomMargin = 0 - viewHeights.get(position);
}
}
/**
* Performs either COLLAPSE or EXPAND animation on the target view
*
* #param target
* the view to animate
* #param type
* the animation type, either ExpandCollapseAnimation.COLLAPSE or ExpandCollapseAnimation.EXPAND
*/
private void animateView(final View target, final int type)
{
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
System.out.println("Animation End");
if (type == ExpandCollapseAnimation.EXPAND)
{
if (parent instanceof ListView)
{
ListView listView = (ListView) parent;
int movement = target.getBottom();
Rect r = new Rect();
boolean visible = target.getGlobalVisibleRect(r);
Rect r2 = new Rect();
listView.getGlobalVisibleRect(r2);
if (!visible)
{
listView.smoothScrollBy(movement, getAnimationDuration());
}
else
{
if (r2.bottom == r.bottom)
{
listView.smoothScrollBy(movement, getAnimationDuration());
}
}
}
}
}
});
target.startAnimation(anim);
}
private void animateWithUpperView(final View target, final int type, final int position)
{
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
// upperViewsList.get(lastOpenItemForUpperView).setVisibility(View.VISIBLE);
// lastOpenItemForUpperView = position;
Animation expandItemAniamtion = new ExpandCollapseLowerViewAnimation(upperViewsList.get(lastOpenItemIndex), ExpandCollapseUpperViewAnimation.EXPAND);
expandItemAniamtion.setDuration(800);
expandItemAniamtion.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation)
{
circleViewsList.get(lastOpenItemIndex).setVisibility(View.VISIBLE);
lastOpenItemIndex = position;
}
});
// Lower view animation
Animation lowerAnim = new ExpandCollapseLowerViewAnimation(lowerViewsList.get(lastOpenItemIndex), ExpandCollapseUpperViewAnimation.EXPAND);
lowerAnim.setDuration(800);
upperViewsList.get(lastOpenItemIndex).startAnimation(expandItemAniamtion);
lowerViewsList.get(lastOpenItemIndex).startAnimation(lowerAnim);
}
});
target.startAnimation(anim);
}
/**
* Closes the current open item. If it is current visible it will be closed with an animation.
*
* #return true if an item was closed, false otherwise
*/
public boolean collapseLastOpen()
{
if (isAnyItemExpanded())
{
// if visible animate it out
if (lastOpen != null)
{
animateView(lastOpen, ExpandCollapseAnimation.COLLAPSE);
}
openItems.set(lastOpenPosition, false);
lastOpenPosition = -1;
return true;
}
return false;
}
public Parcelable onSaveInstanceState(Parcelable parcelable)
{
SavedState ss = new SavedState(parcelable);
ss.lastOpenPosition = this.lastOpenPosition;
ss.openItems = this.openItems;
return ss;
}
public void onRestoreInstanceState(SavedState state)
{
if (state != null)
{
this.lastOpenPosition = state.lastOpenPosition;
this.openItems = state.openItems;
}
}
/**
* Utility methods to read and write a bitset from and to a Parcel
*/
private static BitSet readBitSet(Parcel src)
{
BitSet set = new BitSet();
if (src == null)
{
return set;
}
int cardinality = src.readInt();
for (int i = 0; i < cardinality; i++)
{
set.set(src.readInt());
}
return set;
}
private static void writeBitSet(Parcel dest, BitSet set)
{
int nextSetBit = -1;
if (dest == null || set == null)
{
return; // at least dont crash
}
dest.writeInt(set.cardinality());
while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1)
{
dest.writeInt(nextSetBit);
}
}
/**
* The actual state class
*/
static class SavedState extends View.BaseSavedState
{
public BitSet openItems = null;
public int lastOpenPosition = -1;
SavedState(Parcelable superState)
{
super(superState);
}
private SavedState(Parcel in)
{
super(in);
lastOpenPosition = in.readInt();
openItems = readBitSet(in);
}
#Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeInt(lastOpenPosition);
writeBitSet(out, openItems);
}
// required field that makes Parcelables from a Parcel
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];
}
};
}
public static Animation ExpandOrCollapseView(final View v, final boolean expand)
{
try
{
Method m = v.getClass().getDeclaredMethod("onMeasure", int.class, int.class);
m.setAccessible(true);
m.invoke(v, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(((View) v.getParent()).getMeasuredWidth(), MeasureSpec.AT_MOST));
}
catch (Exception e)
{
e.printStackTrace();
}
final int initialHeight = v.getMeasuredHeight();
if (expand)
{
v.getLayoutParams().height = 0;
}
else
{
v.getLayoutParams().height = initialHeight;
}
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
int newHeight = 0;
if (expand)
{
newHeight = (int) (initialHeight * interpolatedTime);
}
else
{
newHeight = (int) (initialHeight * (1 - interpolatedTime));
}
v.getLayoutParams().height = newHeight;
v.requestLayout();
if (interpolatedTime == 1 && !expand)
v.setVisibility(View.GONE);
}
#Override
public boolean willChangeBounds()
{
return true;
}
};
a.setDuration(1000);
return a;
}}
Luckily I have found the solution. On pre-kitkat the upperView on list item which was gone does not forcelly animate but on kitkat and so on it forcelly animate from gone to visible.
So as the solution we must give a layer of view between of list item and upper view (Which we have to animate).
In this way it will work like charm.
I am using touch listener for an imageview in the listview item .It is working fine when I just do that like an sample application(I mean I have that Listview item as an sample one). But when I put this in a listview it is really becoming very slow.
I just wants to drag the image only horizantally,for that purpose I used ConstrainedDragandDrop View class which I got from the Github.
In my sample application:
public class HorizontalScroll extends Activity {
ImageView full_left,heart;
RelativeLayout rlMainLayout,rlImages,Cartoon_image,half_left,play_btn,centre,centre_leftanimate;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inflated_bloops);
half_left=(RelativeLayout)findViewById(R.id.half_left);
Cartoon_image=(RelativeLayout)findViewById(R.id.cartoon_image);
play_btn=(RelativeLayout)findViewById(R.id.play_btn);
heart=(ImageView)findViewById(R.id.ivheart);
ConstrainedDragAndDropView dndView = (ConstrainedDragAndDropView) findViewById(R.id.dndView);
dndView.setDragHandle(findViewById(R.id.cartoon_image),findViewById(R.id.half_left),heart);
dndView.setAllowVerticalDrag(false,HorizontalScroll.this);
}
}
When I used in my Listview:
public class Cars extends BaseAdapter
{
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
LayoutInflater inflator = getLayoutInflater();
v= inflator.inflate(R.layout.inflated_bloops, null);
ConstrainedDragAndDropView dndView = (ConstrainedDragAndDropView) v.findViewById(R.id.dndView);
dndView.setDragHandle(v.findViewById(R.id.cartoon_image),v.findViewById(R.id.half_left),heart);
dndView.setAllowVerticalDrag(false,FeedModeActivity.this);
RelativeLayout Cartoon_image=(RelativeLayout)v.findViewById(R.id.cartoon_image);
ImageView ivDummy =(ImageView)v.findViewById(R.id.dummy);
try{
loader.DisplayImageRelative( al_new.get(position).replace(" ", "%20"),ivDummy, Cartoon_image);
}
catch(Exception e){
e.printStackTrace();
}
return v;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return al_new.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
Here is my custom dragDrop view:
public class ConstrainedDragAndDropView extends LinearLayout {
Activity main;
protected View dragHandle,half,heart;
protected List<View> dropTargets = new ArrayList<View>();
protected boolean dragging = false;
protected int pointerId;
protected int selectedDropTargetIndex = -1;
protected int lastSelectedDropTargetIndex = -1;
protected int lastDroppedIndex = -1;
protected boolean allowHorizontalDrag = true;
protected boolean allowVerticalDrag = true;
protected DropListener dropListener;
public interface DropListener {
public void onDrop(final int dropIndex, final View dropTarget);
}
public ConstrainedDragAndDropView(Context context) {
super(context);
}
public ConstrainedDragAndDropView(Context context, AttributeSet attrs) {
super(context, attrs);
applyAttrs(context, attrs);
}
#SuppressLint("NewApi")
public ConstrainedDragAndDropView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
applyAttrs(context, attrs);
}
public DropListener getDropListener() {
return dropListener;
}
public void setDropListener(DropListener dropListener) {
this.dropListener = dropListener;
}
public View getDragHandle() {
return dragHandle;
}
public void setDragHandle(View dragHandle,View half_left,View heart) {
this.dragHandle = dragHandle;
this.half=half_left;
this.heart=heart;
setupDragHandle();
}
public List<View> getDropTargets() {
return dropTargets;
}
public void setDropTargets(List<View> dropTargets) {
this.dropTargets = dropTargets;
}
public void addDropTarget(View target) {
if (dropTargets == null) {
dropTargets = new ArrayList<View>();
}
dropTargets.add(target);
}
public boolean isAllowHorizontalDrag() {
return allowHorizontalDrag;
}
public void setAllowHorizontalDrag(boolean allowHorizontalDrag) {
this.allowHorizontalDrag = allowHorizontalDrag;
}
public boolean isAllowVerticalDrag() {
return allowVerticalDrag;
}
public void setAllowVerticalDrag(boolean allowVerticalDrag,Activity c) {
this.allowVerticalDrag = allowVerticalDrag;
this.main=c;
}
protected void applyAttrs(Context context, AttributeSet attrs) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ConstrainedDragAndDropView, 0, 0);
try {
/*
layoutId = a.getResourceId(R.styleable.ConstrainedDragAndDropView_layoutId, 0);
if (layoutId > 0) {
LayoutInflater.from(context).inflate(layoutId, this, true);
}
*/
} finally {
a.recycle();
}
}
protected void setupDragHandle() {
this.setOnTouchListener(new DragAreaTouchListener());
}
protected class DragAreaTouchListener implements OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("Action down", "action down in listener");
onActionDown(view, motionEvent);
break;
case MotionEvent.ACTION_UP:
Log.d("Action up", "action up in listener");
onActionUp(view, motionEvent);
break;
case MotionEvent.ACTION_MOVE:
Log.d("Action move", "action move in listener");
onActionMove(view, motionEvent);
break;
default:
break;
}
return true;
}
}
public static int param;
protected void onActionDown(View view, MotionEvent motionEvent) {
// if we're not already dragging, and the touch position is on the drag handle,
// then start dragging
if(!dragging && isDragHandleTouch(motionEvent)) {
pointerId = motionEvent.getPointerId(0);
Float s1= dragHandle.getX();
param=Integer.valueOf(s1.intValue());
Log.e("param",""+param);
// updateDragPosition(motionEvent);
dragging = true;
Log.d("drag", "drag start");
}
}
protected void onActionUp(View view, MotionEvent motionEvent) {
Log.d("Action up", "action up");
// if we're dragging, then stop dragging
if (dragging && motionEvent.getPointerId(0) == pointerId) {
Log.e("condition","satisfied");
Log.e("x val"+(int)motionEvent.getX(),"y val"+(int)motionEvent.getY());
Log.e("x1"+half.getLeft(),"y1"+half.getTop());
Log.e("x4"+half.getRight(),"y4"+half.getBottom());
Float s1=motionEvent.getX();
Float s2=motionEvent.getY();
int x=Integer.valueOf(s1.intValue());
dragging = false;
int y=Integer.valueOf(s2.intValue());
if((half.getLeft()<x)&&(x<half.getRight())&&((half.getTop()<y)&&(y<half.getBottom())))
{
Log.e("drop","on target");
try {
Thread.sleep(1000);
dragHandle.setX(param);
heart.setVisibility(View.VISIBLE);
Animation pulse = AnimationUtils.loadAnimation(main, R.anim.pulse);
heart.startAnimation(pulse);
// heart.setVisibility(View.GONE);
pulse.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
Log.e("animation","start");
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
Log.e("animation","end");
heart.setVisibility(View.GONE);
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// class SimpleThread extends Thread {
//
// public void run() {
//
// try {
// sleep(1000);
// runOnUiThread(new Runnable() {
// public void run() {
// dragHandle.setX(param);
// heart.setVisibility(View.VISIBLE);
//
// Animation pulse = AnimationUtils.loadAnimation(main, R.anim.pulse);
// heart.startAnimation(pulse);
// }
// });
//
// }
// catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// }
// }
//
// new SimpleThread().start();
}
else{
Log.e("drop",""+"outside target");
dragHandle.setX(param);
// TranslateAnimation transAnimation= new TranslateAnimation(x, 300, y, 300);
// transAnimation.setDuration(1000);//set duration
// view.startAnimation(transAnimation);
}
// if()
// updateDragPosition(motionEvent);
Log.d("drag", "drag end");
// find out what drop target, if any, the drag handle was dropped on
int dropTargetIndex = findDropTargetIndexUnderDragHandle();
if(dropTargetIndex >= 0) { // if drop was on a target, select the target
Log.d("drag", "drop on target " + dropTargetIndex);
// selectDropTarget(dropTargetIndex);
// snapDragHandleToDropTarget(dropTargetIndex);
// lastDroppedIndex = dropTargetIndex;
if(dropListener != null) {
dropListener.onDrop(dropTargetIndex, dropTargets.get(dropTargetIndex));
}
} else { // if drop was not on a target, re-select the last selected target
// deselectDropTarget();
// snapDragHandleToDropTarget(lastDroppedIndex);
}
}
else{
Log.e("condition not","satisfied");
}
}
protected void onActionMove(View view, MotionEvent motionEvent) {
Log.d("Action move", "action move");
if (dragging && motionEvent.getPointerId(0) == pointerId) {
updateDragPosition(motionEvent);
int dropTargetIndex = findDropTargetIndexUnderDragHandle();
if(dropTargetIndex >= 0) {
Log.d("drag", "hover on target " + dropTargetIndex);
// selectDropTarget(dropTargetIndex);
} else {
// deselectDropTarget();
}
}
}
#SuppressLint("NewApi")
protected void updateDragPosition(MotionEvent motionEvent) {
// this is where we constrain the movement of the dragHandle
if(allowHorizontalDrag) {
float candidateX = motionEvent.getX() - dragHandle.getWidth() / 2;
if(candidateX > 0 && candidateX + dragHandle.getWidth() < this.getWidth()) {
dragHandle.setX(candidateX);
}
}
if(allowVerticalDrag) {
float candidateY = motionEvent.getY() - dragHandle.getHeight() / 2;
if(candidateY > 0 && candidateY + dragHandle.getHeight() < this.getHeight()) {
dragHandle.setY(candidateY);
}
}
}
#SuppressLint("NewApi")
protected void snapDragHandleToDropTarget(int dropTargetIndex) {
if(dropTargetIndex > -1) {
View dropTarget = dropTargets.get(dropTargetIndex);
float xCenter = dropTarget.getX() + dropTarget.getWidth() / 2;
float yCenter = dropTarget.getY() + dropTarget.getHeight() / 2;
float xOffset = dragHandle.getWidth() / 2;
float yOffset = dragHandle.getHeight() / 2;
float x = xCenter - xOffset;
float y = yCenter - yOffset;
dragHandle.setX(x);
dragHandle.setY(y);
}
}
protected boolean isDragHandleTouch(MotionEvent motionEvent) {
Point point = new Point(
new Float(motionEvent.getRawX()).intValue(),
new Float(motionEvent.getRawY()).intValue()
);
return isPointInView(point, dragHandle);
}
protected int findDropTargetIndexUnderDragHandle() {
int dropTargetIndex = -1;
for(int i = 0; i < dropTargets.size(); i++) {
if(isCollision(dragHandle, dropTargets.get(i))) {
dropTargetIndex = i;
break;
}
}
return dropTargetIndex;
}
/**
* Determines whether a raw screen coordinate is within the bounds of the specified view
* #param point - Point containing screen coordinates
* #param view - View to test
* #return true if the point is in the view, else false
*/
protected boolean isPointInView(Point point, View view) {
int[] viewPosition = new int[2];
view.getLocationOnScreen(viewPosition);
int left = viewPosition[0];
int right = left + view.getWidth();
int top = viewPosition[1];
int bottom = top + view.getHeight();
return point.x >= left && point.x <= right && point.y >= top && point.y <= bottom;
}
#SuppressLint("NewApi")
protected boolean isCollision(View view1, View view2) {
boolean collision = false;
do {
if(view1.getY() + view1.getHeight() < view2.getY()) {
break;
}
if(view1.getY() > view2.getY() + view2.getHeight()) {
break;
}
if(view1.getX() > view2.getX() + view2.getWidth()) {
break;
}
if(view1.getX() + view1.getWidth() < view2.getX()) {
break;
}
collision = true;
} while(false);
return collision;
}
protected void selectDropTarget(int index) {
if(index > -1) {
deselectDropTarget();
selectedDropTargetIndex = index;
dropTargets.get(selectedDropTargetIndex).setSelected(true);
}
}
protected void deselectDropTarget() {
if(selectedDropTargetIndex > -1) {
dropTargets.get(selectedDropTargetIndex).setSelected(false);
lastSelectedDropTargetIndex = selectedDropTargetIndex;
selectedDropTargetIndex = -1;
}
}
}
In details, I am looking for an example exactly like below image. I got a good example in this link https://github.com/woozzu/IndexableListView. Its works fine as my requirement.But problem when i implementing to my project it is showing error in list view. below is my code plz help me. i am new to this topic. Thank you in advance!
looking for:
here is my code below plz say my mistake..
MainActivity .java
public class MainActivity extends Activity implements SearchView.OnQueryTextListener,SearchView.OnCloseListener {
private ListView listView;
private SearchView search;
EfficientAdapter objectAdapter;
EfficientAdapter2 objectAdapter1;
int textlength=0;
private CheckBox checkStat, checkRoutine, checkTat;
private GestureDetector mGestureDetector;
private ArrayList<CountriesList> elements;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.homempleb);
Log.i("scan"," txtScanResult ");
//Arrays.sort(CountriesList.name);
ActionItem nextItem = new ActionItem();
final QuickAction quickAction = new QuickAction(this, QuickAction.VERTICAL);
quickAction.addActionItem(nextItem);
quickAction.setOnDismissListener(new QuickAction.OnDismissListener() {
#Override
public void onDismiss() {
Toast.makeText(getApplicationContext(), "Dismissed", Toast.LENGTH_SHORT).show();
}
});
search = (SearchView) findViewById(R.id.searchView1);
search.setIconifiedByDefault(false);
search.setOnQueryTextListener(this);
search.setOnCloseListener(this);
search.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
quickAction.show(v);
}
});
checkStat = (CheckBox) findViewById(R.id.checkBoxStat);
checkRoutine = (CheckBox) findViewById(R.id.checkBoxRoutine);
checkTat = (CheckBox) findViewById(R.id.checkBoxTat);
checkStat.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
checkStat.setChecked(true);
Toast.makeText(MainActivity.this, "STAT", Toast.LENGTH_SHORT).show();
checkRoutine.setChecked(false);
checkTat.setChecked(false);
}
}
});
checkRoutine.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
checkRoutine.setChecked(true);
Toast.makeText(MainActivity.this, "ROUTINE", Toast.LENGTH_SHORT).show();
checkStat.setChecked(false);
checkTat.setChecked(false);
}
}
});
checkTat.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
checkTat.setChecked(true);
Toast.makeText(MainActivity.this, "TAT Effeciency", Toast.LENGTH_SHORT).show();
checkRoutine.setChecked(false);
checkStat.setChecked(false);
}
}
});
listView = (ListView) findViewById(R.id.homelistView);
listView.setTextFilterEnabled(true);
listView.setFastScrollEnabled(true);
objectAdapter = new EfficientAdapter(this, elements );
listView.setAdapter(objectAdapter);
Button refreshButton= (Button)findViewById(R.id.refreshButton);
refreshButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
objectAdapter1 = new EfficientAdapter2(MainActivity.this);
// objectAdapter = new EfficientAdapter(MainActivity.this);// adapter with new data
listView.setAdapter(objectAdapter1);
Log.i("notifyDataSetChanged", "data updated");
objectAdapter1.notifyDataSetChanged();
}
});
}
#Override
public boolean onClose() {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
}
EfficientAdapter.java
public class EfficientAdapter extends BaseAdapter implements SectionIndexer {
private AlphabetIndexer alphaIndexer;
private String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private LayoutInflater mInflater;
private Context context;
public EfficientAdapter(Context context, ArrayList<CountriesList> elements) {
mInflater = LayoutInflater.from(context);
this.context=context;
}
public int getCount() {
return CountriesList.name.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.homemplebrowview, null);
holder = new ViewHolder();
holder.text1 = (TextView) convertView
.findViewById(R.id.name);
holder.text2 = (TextView) convertView
.findViewById(R.id.mrn);
holder.text3 = (TextView) convertView
.findViewById(R.id.date);
holder.text4 = (TextView) convertView
.findViewById(R.id.age);
holder.text5 = (TextView) convertView
.findViewById(R.id.gender);
holder.text6 = (TextView) convertView
.findViewById(R.id.wardno);
holder.text7 = (TextView) convertView
.findViewById(R.id.roomno);
holder.text8 = (TextView) convertView
.findViewById(R.id.bedno);
holder.btnList = (Button)convertView.findViewById(R.id.listbutton);
// holder.btnList.setOnClickListener(this);
holder.btnList.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent next=new Intent(context, SeviceDetails.class);
context.startActivity(next);
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text1.setText(CountriesList.name[position]);
holder.text2.setText(CountriesList.mrn[position]);
holder.text3.setText(CountriesList.actualstart[position]);
holder.text4.setText(CountriesList.age[position]);
holder.text5.setText(CountriesList.gender[position]);
holder.text6.setText(CountriesList.wardNo[position]);
holder.text7.setText(CountriesList.roomNo[position]);
holder.text8.setText(CountriesList.bedNo[position]);
return convertView;
}
static class ViewHolder {
public Button btnList;
public TextView text8;
public TextView text7;
public TextView text6;
public TextView text5;
public TextView text4;
public TextView text1;
public TextView text2;
public TextView text3;
}
#Override
public void notifyDataSetChanged()
{
super.notifyDataSetChanged();
}
#Override
public int getPositionForSection(int section) {
// If there is no item for current section, previous section will be selected
for (int i = section; i >= 0; i--) {
for (int j = 0; j < getCount(); j++) {
if (i == 0) {
// For numeric section
for (int k = 0; k <= 9; k++) {
// if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(k)))
return j;
}
} else {
// if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(mSections.charAt(i))))
return j;
}
}
}
return 0;
}
#Override
public int getSectionForPosition(int position) {
return 0;
}
#Override
public Object[] getSections() {
String[] sections = new String[mSections.length()];
for (int i = 0; i < mSections.length(); i++)
sections[i] = String.valueOf(mSections.charAt(i));
return sections;
}
}
IndexableListView.java
public class IndexableListView extends ListView {
private boolean mIsFastScrollEnabled = false;
private IndexScroller mScroller = null;
private GestureDetector mGestureDetector = null;
public IndexableListView(Context context) {
super(context);
}
public IndexableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public IndexableListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean isFastScrollEnabled() {
return mIsFastScrollEnabled;
}
#Override
public void setFastScrollEnabled(boolean enabled) {
mIsFastScrollEnabled = enabled;
if (mIsFastScrollEnabled) {
if (mScroller == null)
mScroller = new IndexScroller(getContext(), this);
} else {
if (mScroller != null) {
mScroller.hide();
mScroller = null;
}
}
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
// Overlay index bar
if (mScroller != null)
mScroller.draw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Intercept ListView's touch event
if (mScroller != null && mScroller.onTouchEvent(ev))
return true;
if (mGestureDetector == null) {
mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
// If fling happens, index bar shows
mScroller.show();
return super.onFling(e1, e2, velocityX, velocityY);
}
});
}
mGestureDetector.onTouchEvent(ev);
return super.onTouchEvent(ev);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
#Override
public void setAdapter(ListAdapter adapter) {
super.setAdapter(adapter);
if (mScroller != null)
mScroller.setAdapter(adapter);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mScroller != null)
mScroller.onSizeChanged(w, h, oldw, oldh);
}
}
StringMatcher.java
public class StringMatcher {
public static boolean match(String value, String keyword) {
if (value == null || keyword == null)
return false;
if (keyword.length() > value.length())
return false;
int i = 0, j = 0;
do {
if (isKorean(value.charAt(i)) && isInitialSound(keyword.charAt(j))) {
} else {
if (keyword.charAt(j) == value.charAt(i)) {
i++;
j++;
} else if (j > 0)
break;
else
i++;
}
} while (i < value.length() && j < keyword.length());
return (j == keyword.length())? true : false;
}
private static boolean isKorean(char c) {
return false;
}
private static boolean isInitialSound(char c) {
return false;
}
}
IndexScroller.java
public class IndexScroller {
private static final int STATE_HIDDEN = 0;
private static final int STATE_SHOWING = 1;
private static final int STATE_SHOWN = 2;
private static final int STATE_HIDING = 3;
public IndexScroller(Context context, ListView lv) {
mDensity = context.getResources().getDisplayMetrics().density;
mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
mListView = lv;
setAdapter(mListView.getAdapter());
mIndexbarWidth = 20 * mDensity;
mIndexbarMargin = 10 * mDensity;
mPreviewPadding = 5 * mDensity;
}
public void draw(Canvas canvas) {
if (mState == STATE_HIDDEN)
return;
// mAlphaRate determines the rate of opacity
Paint indexbarPaint = new Paint();
indexbarPaint.setColor(Color.BLACK);
indexbarPaint.setAlpha((int) (64 * mAlphaRate));
indexbarPaint.setAntiAlias(true);
canvas.drawRoundRect(mIndexbarRect, 5 * mDensity, 5 * mDensity, indexbarPaint);
if (mSections != null && mSections.length > 0) {
// Preview is shown when mCurrentSection is set
if (mCurrentSection >= 0) {
Paint previewPaint = new Paint();
previewPaint.setColor(Color.BLACK);
previewPaint.setAlpha(96);
previewPaint.setAntiAlias(true);
previewPaint.setShadowLayer(3, 0, 0, Color.argb(64, 0, 0, 0));
Paint previewTextPaint = new Paint();
previewTextPaint.setColor(Color.WHITE);
previewTextPaint.setAntiAlias(true);
previewTextPaint.setTextSize(50 * mScaledDensity);
float previewTextWidth = previewTextPaint.measureText(mSections[mCurrentSection]);
float previewSize = 2 * mPreviewPadding + previewTextPaint.descent() - previewTextPaint.ascent();
RectF previewRect = new RectF((mListViewWidth - previewSize) / 2
, (mListViewHeight - previewSize) / 2
, (mListViewWidth - previewSize) / 2 + previewSize
, (mListViewHeight - previewSize) / 2 + previewSize);
canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity, previewPaint);
canvas.drawText(mSections[mCurrentSection], previewRect.left + (previewSize - previewTextWidth) / 2 - 1
, previewRect.top + mPreviewPadding - previewTextPaint.ascent() + 1, previewTextPaint);
}
Paint indexPaint = new Paint();
indexPaint.setColor(Color.WHITE);
indexPaint.setAlpha((int) (255 * mAlphaRate));
indexPaint.setAntiAlias(true);
indexPaint.setTextSize(12 * mScaledDensity);
float sectionHeight = (mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length;
float paddingTop = (sectionHeight - (indexPaint.descent() - indexPaint.ascent())) / 2;
for (int i = 0; i < mSections.length; i++) {
float paddingLeft = (mIndexbarWidth - indexPaint.measureText(mSections[i])) / 2;
canvas.drawText(mSections[i], mIndexbarRect.left + paddingLeft
, mIndexbarRect.top + mIndexbarMargin + sectionHeight * i + paddingTop - indexPaint.ascent(), indexPaint);
}
}
}
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// If down event occurs inside index bar region, start indexing
if (mState != STATE_HIDDEN && contains(ev.getX(), ev.getY())) {
setState(STATE_SHOWN);
// It demonstrates that the motion event started from index bar
mIsIndexing = true;
// Determine which section the point is in, and move the list to that section
mCurrentSection = getSectionByPoint(ev.getY());
mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
return true;
}
break;
case MotionEvent.ACTION_MOVE:
if (mIsIndexing) {
// If this event moves inside index bar
if (contains(ev.getX(), ev.getY())) {
// Determine which section the point is in, and move the list to that section
mCurrentSection = getSectionByPoint(ev.getY());
mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
}
return true;
}
break;
case MotionEvent.ACTION_UP:
if (mIsIndexing) {
mIsIndexing = false;
mCurrentSection = -1;
}
if (mState == STATE_SHOWN)
setState(STATE_HIDING);
break;
}
return false;
}
public void onSizeChanged(int w, int h, int oldw, int oldh) {
mListViewWidth = w;
mListViewHeight = h;
mIndexbarRect = new RectF(w - mIndexbarMargin - mIndexbarWidth
, mIndexbarMargin
, w - mIndexbarMargin
, h - mIndexbarMargin);
}
public void show() {
if (mState == STATE_HIDDEN)
setState(STATE_SHOWING);
else if (mState == STATE_HIDING)
setState(STATE_HIDING);
}
public void hide() {
if (mState == STATE_SHOWN)
setState(STATE_HIDING);
}
public void setAdapter(Adapter adapter) {
if (adapter instanceof SectionIndexer) {
mIndexer = (SectionIndexer) adapter;
mSections = (String[]) mIndexer.getSections();
}
}
private void setState(int state) {
if (state < STATE_HIDDEN || state > STATE_HIDING)
return;
mState = state;
switch (mState) {
case STATE_HIDDEN:
// Cancel any fade effect
mHandler.removeMessages(0);
break;
case STATE_SHOWING:
// Start to fade in
mAlphaRate = 0;
fade(0);
break;
case STATE_SHOWN:
// Cancel any fade effect
mHandler.removeMessages(0);
break;
case STATE_HIDING:
// Start to fade out after three seconds
mAlphaRate = 1;
fade(3000);
break;
}
}
private boolean contains(float x, float y) {
// Determine if the point is in index bar region, which includes the right margin of the bar
return (x >= mIndexbarRect.left && y >= mIndexbarRect.top && y <= mIndexbarRect.top + mIndexbarRect.height());
}
private int getSectionByPoint(float y) {
if (mSections == null || mSections.length == 0)
return 0;
if (y < mIndexbarRect.top + mIndexbarMargin)
return 0;
if (y >= mIndexbarRect.top + mIndexbarRect.height() - mIndexbarMargin)
return mSections.length - 1;
return (int) ((y - mIndexbarRect.top - mIndexbarMargin) / ((mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length));
}
private void fade(long delay) {
mHandler.removeMessages(0);
mHandler.sendEmptyMessageAtTime(0, SystemClock.uptimeMillis() + delay);
}
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (mState) {
case STATE_SHOWING:
// Fade in effect
mAlphaRate += (1 - mAlphaRate) * 0.2;
if (mAlphaRate > 0.9) {
mAlphaRate = 1;
setState(STATE_SHOWN);
}
mListView.invalidate();
fade(10);
break;
case STATE_SHOWN:
// If no action, hide automatically
setState(STATE_HIDING);
break;
case STATE_HIDING:
// Fade out effect
mAlphaRate -= mAlphaRate * 0.2;
if (mAlphaRate < 0.1) {
mAlphaRate = 0;
setState(STATE_HIDDEN);
}
mListView.invalidate();
fade(10);
break;
}
}
};
}
if i add this it works code in mainactivity
listView = (ListView) findViewById(R.id.homelistView);
your are using a custom ListView class, com.woozzu.android.widget.IndexableListView
You have to replace your "ListView " in layout file to a "com.woozzu.android.widget.IndexableListView"
Change your Layout to:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:background="#ff3344"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#ffffff"
android:layout_alignTop="#+id/scrollView1"
android:layout_toRightOf="#+id/scrollView1" >
<com.woozzu.android.widget.IndexableListView
android:id="#+id/homelistView"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1.04"
android:dividerHeight="0dip" >
</com.woozzu.android.widget.IndexableListView>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
The solution Suggested by #Anis is the only working solution I found. In addition to that, If you want Click listeners to components on your List View Items, you have to update the Code as mentioned here, https://github.com/denley/IndexableListView/commit/18210a54487ba079bb332fafec709e2de26883db