0
我看過文章"Listview slide to remove"
,現在想實現"Listview to Highlight"
想想,所以基本上我想改變所選行的背景顏色。問題是當我突出顯示一行時,它會自動突出顯示另一個不可見的行。 (我需要向下滾動才能看到它)更改列表視圖行的背景
這裏是我的代碼(其實不是我的):
MainActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_deletion);
mListView = (ListView) findViewById(R.id.listview);
mainView = (LinearLayout) findViewById(R.id.listViewBackground1);
final ArrayList<String> cheeseList = new ArrayList<String>();
for (int i = 0; i < Cheeses.sCheeseStrings.length; ++i) {
cheeseList.add(Cheeses.sCheeseStrings[i]);
}
mAdapter = new StableArrayAdapter(this,R.layout.opaque_text_view, cheeseList, mTouchListener);
mListView.setAdapter(mAdapter);
}
private View.OnTouchListener mTouchListener = new View.OnTouchListener() {
float mDownX;
private int mSwipeSlop = -1;
@Override
public boolean onTouch(final View v, MotionEvent event) {
if (mSwipeSlop < 0) {
mSwipeSlop = ViewConfiguration.get(ListViewRemovalAnimation.this).
getScaledTouchSlop();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mItemPressed) {
return false;
}
mItemPressed = true;
mDownX = event.getX();
break;
case MotionEvent.ACTION_CANCEL:
v.setTranslationX(0);
mItemPressed = false;
break;
case MotionEvent.ACTION_MOVE:
{
float x = event.getX() + v.getTranslationX();
float deltaX = x - mDownX;
float deltaXAbs = Math.abs(deltaX);
if(deltaX > 0.0) {
mainView.setBackgroundColor(Color.GREEN);
}
else {
mainView.setBackgroundColor(Color.RED);
}
if (!mSwiping) {
if (deltaXAbs > mSwipeSlop) {
mSwiping = true;
mListView.requestDisallowInterceptTouchEvent(true);
}
}
if (mSwiping) {
v.setTranslationX((x - mDownX));
}
}
break;
case MotionEvent.ACTION_UP:
{if (mSwiping) {
float x = event.getX() + v.getTranslationX();
float deltaX = x - mDownX;
float deltaXAbs = Math.abs(deltaX);
float fractionCovered;
float endX;
final boolean remove;
final boolean removeOr;
if (deltaXAbs > v.getWidth()/4) {
// Greater than a quarter of the width - animate it out
fractionCovered = deltaXAbs/v.getWidth();
endX = deltaX < 0 ? -v.getWidth() : v.getWidth();
remove = true;
} else {
// Not far enough - animate it back
fractionCovered = 1 - (deltaXAbs/v.getWidth());
endX = 0;
remove = false;
}
removeOr = (deltaX > 0 ? true : false);
long duration = (int) ((1 - fractionCovered) * SWIPE_DURATION);
mListView.setEnabled(false);
v.animate().setDuration(duration).translationX(endX).
withEndAction(new Runnable() {
@Override
public void run() {
v.setTranslationX(0);
if (remove) {
//int position = mListView.getPositionForView(v);
//mAdapter.remove(mAdapter.getItem(position));
animateRemoval(mListView, v, removeOr);
} else {
mSwiping = false;
mListView.setEnabled(true);
}
}
});
}
}
mItemPressed = false;
break;
default:
return false;
}
return true;
}
};
private void animateRemoval(final ListView listview, View viewToRemove, boolean removeOr) {
int firstVisiblePosition = listview.getFirstVisiblePosition(); //first visible position in listview
for (int i = 0; i < listview.getChildCount(); ++i) { // iterate 11 visible elements
View child = listview.getChildAt(i); // current visible element
if (child != viewToRemove) { // if the current item is not the one we need to remove
int position = firstVisiblePosition + i; // relative index
long itemId = mAdapter.getItemId(position); // global index (constant)
mItemIdTopMap.put(itemId, child.getTop()); // putto the map
}
}
int position = mListView.getPositionForView(viewToRemove); // position to remove from listview (relative)
if(removeOr == false) mAdapter.remove(mAdapter.getItem(position));
else {
//Log.w("----", "sample");
viewToRemove.setBackgroundColor(Color.GREEN);
}
//
//
//
//SAVE TO THE MAP AND REMOVE FROM ADAPTER
//
//
//
final ViewTreeObserver observer = listview.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
observer.removeOnPreDrawListener(this); // remove previous callback
boolean firstAnimation = true; // flag for animation algo
int firstVisiblePosition = listview.getFirstVisiblePosition(); //first visible view index
for (int i = 0; i < listview.getChildCount(); ++i) { //iterate 11 visible elements
final View child = listview.getChildAt(i); // current view (by child)
int position = firstVisiblePosition + i; // relative index of item
long itemId = mAdapter.getItemId(position); // global index of item (constant)
Integer startTop = mItemIdTopMap.get(itemId); // top position of global item
int top = child.getTop(); // top position of current item
/*
If we deleted the element from visible listview area, then we have new element
from non-visible listview area. That is the situation when starTop == null (if
top position of global item "itemId" was in unvisible area before deletion.)
*/
if (startTop != null) { // item was in visible area before the deletion
if (startTop != top) { // if startop != top (when the deleted element was after the current)
int delta = startTop - top; // initial top
child.setTranslationY(delta); // set init top
child.animate().setDuration(MOVE_DURATION).translationY(0); // animate to 0
if (firstAnimation) { // if it is the first animation
child.animate().withEndAction(new Runnable() { // call end action
public void run() {
mSwiping = false; // so we can swipe again
mListView.setEnabled(true); // enable listview touch events
}
});
firstAnimation = false; //
}
}
}
else {
int childHeight = child.getHeight() + listview.getDividerHeight(); // height of listview child view
startTop = top + childHeight; // new top for currently unvisible element
int delta = startTop - top; // initial top
child.setTranslationY(delta); // set init top
child.animate().setDuration(MOVE_DURATION).translationY(0); // animate to top 0
/*
if it is the first animation. It happens whwn we removed last visible element from listview.
So we didn't use firstAnimation flag.
*/
if (firstAnimation) { // if it is the first animation
child.animate().withEndAction(new Runnable() { // call end action
public void run() {
mSwiping = false; // so we can swipe again
mListView.setEnabled(true); // enable listview touch events
}
});
firstAnimation = false; //
}
}
}
mItemIdTopMap.clear(); // free memory
return true;
}
});
}
StableArrayAdapter:
public class StableArrayAdapter extends ArrayAdapter<String> {
HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
View.OnTouchListener mTouchListener;
public StableArrayAdapter(Context context, int textViewResourceId,
List<String> objects, View.OnTouchListener listener) {
super(context, textViewResourceId, objects);
mTouchListener = listener;
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
@Override
public long getItemId(int position) {
String item = getItem(position);
return mIdMap.get(item);
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.setOnTouchListener(mTouchListener);
return view;
}
}
但我想用Java和動態實現它。可能嗎? – James