草庐IT

android - 在 ListView 中实现滑动

coder 2023-12-09 原文

我想像Samsung Android Phones调用功能一样在ListView中实现Swipe

我有一个列表,如下图所示:

现在,当我从左侧滑动一定距离(即 25% 的距离)向右侧滑动时,它只是改变了背景,就像三星设备中的调用功能或 SwipeListView 一样:

为此需要解决方案。

最佳答案

试试这段代码:

main.xml文件

<ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</ListView>


原始文件.xml

<TextView
    android:id="@+id/name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginLeft="10dp"
    android:gravity="left"
    android:text="ABC"
    android:textSize="22sp" />

<LinearLayout
    android:id="@+id/delete_lay"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#55ff0000"
    android:visibility="gone" >

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ic_menu_delete"
        android:visibility="visible" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:gravity="left"
        android:text="Deleting..."
        android:textColor="#ff0000"
        android:textSize="22sp"
        android:textStyle="bold" />
</LinearLayout>


主 Activity .java

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import de.timroes.swipetodismiss.SwipeDismissList;
import de.timroes.swipetodismiss.SwipeDismissList.SwipeDirection;
import de.timroes.swipetodismiss.SwipeDismissList.UndoMode;
import de.timroes.swipetodismiss.SwipeDismissList.Undoable;

public class MainActivity extends Activity {

ArrayList<String> listData;
ListView listView;
ArrayAdapter<String> adapter;
SwipeListAdapter listAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    listView = (ListView) findViewById(R.id.listView1);

    listData = new ArrayList<String>();
    listData.add("item 1");
    listData.add("item 2");
    listData.add("item 3");
    listData.add("item 4");
    listData.add("item 5");
    listData.add("item 6");
    listData.add("item 7");
    listData.add("item 8");
    listData.add("item 9");
    listData.add("item 10");
    listData.add("item 11");
    listData.add("item 12");
    listData.add("item 13");
    listData.add("item 14");
    listData.add("item 15");
    listData.add("item 16");
    listData.add("item 17");

    listAdapter = new SwipeListAdapter(MainActivity.this);
    listView.setAdapter(listAdapter);

    listAdapter.notifyDataSetChanged();
    SwipeDismissList.OnDismissCallback callback = new SwipeDismissList.OnDismissCallback() {
        @Override
        public Undoable onDismiss(AbsListView listView, int position) {
            View view = (View) listView.getChildAt(0);

            view.animate().alpha(1).setDuration(200).translationX(10);
            listAdapter.remove(position);
            return null;
        }
    };

    UndoMode mode = SwipeDismissList.UndoMode.SINGLE_UNDO;

    SwipeDismissList swipeList = new SwipeDismissList(listView, callback,
            mode);
    swipeList.setSwipeDirection(SwipeDirection.END);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

class SwipeListAdapter extends BaseAdapter {

    Context mContext;

    public SwipeListAdapter(Context context) {
        this.mContext = context;
    }

    @Override
    public int getCount() {
        return listData.size();
    }

    @Override
    public Object getItem(int position) {
        return listData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    private void remove(int pos) {
        listData.remove(pos);
        notifyDataSetChanged();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        try {
            if (convertView == null) {
                convertView = LayoutInflater.from(mContext).inflate(
                        R.layout.raw, null);
            }
            TextView textView = (TextView) convertView
                    .findViewById(R.id.name);
            textView.setText(listData.get(position));

            RelativeLayout layout = (RelativeLayout) convertView
                    .findViewById(R.id.parentLayout);

            LayoutParams params = new LayoutParams(
                    LayoutParams.MATCH_PARENT, 50);
            layout.setLayoutParams(params);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return convertView;
    }

}

}

SwipeDismissList.java

import static com.nineoldandroids.view.ViewHelper.setAlpha;
import static com.nineoldandroids.view.ViewHelper.setTranslationX;
import static com.nineoldandroids.view.ViewPropertyAnimator.animate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ValueAnimator;


public final class SwipeDismissList implements View.OnTouchListener {

// Cached ViewConfiguration and system-wide constant values
private int mSlop;
private int mMinFlingVelocity;
private int mMaxFlingVelocity;
private long mAnimationTime;

// Fixed properties
private AbsListView mListView;
private OnDismissCallback mCallback;
private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero

// Transient properties
private SortedSet<PendingDismissData> mPendingDismisses = new TreeSet<PendingDismissData>();
private int mDismissAnimationRefCount = 0;
private float mDownX;
private boolean mSwiping;
private VelocityTracker mVelocityTracker;
private int mDownPosition;
private View mDownView;
private boolean mPaused;
private float mDensity;
private boolean mSwipeDisabled;

private UndoMode mMode;
private List<Undoable> mUndoActions;
private Handler mHandler;

private PopupWindow mUndoPopup;
private TextView mUndoText;
private Button mUndoButton;

private SwipeDirection mSwipeDirection = SwipeDirection.BOTH;
private int mAutoHideDelay = 5000;
private String mDeleteString = "Item deleted";
private String mDeleteMultipleString = "%d items deleted";
private boolean mTouchBeforeAutoHide = true;

private int mDelayedMsgId;

View frontView;
View backView;
RelativeLayout layout ;


public enum UndoMode {

    SINGLE_UNDO,


    MULTI_UNDO,


    COLLAPSED_UNDO
};


public enum SwipeDirection {

    BOTH,

    START,

    END
}


public interface OnDismissCallback {


    Undoable onDismiss(AbsListView listView, int position);
}


public abstract static class Undoable {


    public String getTitle() {
        return null;
    }


    public abstract void undo();


    public void discard() { }

}


public SwipeDismissList(AbsListView listView, OnDismissCallback callback) {
    this(listView, callback, UndoMode.SINGLE_UNDO);
}


public SwipeDismissList(AbsListView listView, OnDismissCallback callback, UndoMode mode) {

    if(listView == null) {
        throw new IllegalArgumentException("listview must not be null.");
    }

    mHandler = new HideUndoPopupHandler();
    mListView = listView;
    mCallback = callback;
    mMode = mode;

    ViewConfiguration vc = ViewConfiguration.get(listView.getContext());
    mSlop = vc.getScaledTouchSlop();
    mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
    mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
    mAnimationTime = listView.getContext().getResources().getInteger(
        android.R.integer.config_shortAnimTime);

    mDensity = mListView.getResources().getDisplayMetrics().density;

    // -- Load undo popup --
    LayoutInflater inflater = (LayoutInflater) mListView.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = inflater.inflate(R.layout.undo_popup, null);
    mUndoButton = (Button)v.findViewById(R.id.undo);
    mUndoButton.setOnClickListener(new UndoHandler());
    mUndoButton.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            // If user tabs "undo" button, reset delay time to remove popup
            mDelayedMsgId++;
            return false;
        }
    });
    mUndoText = (TextView)v.findViewById(R.id.text);

    mUndoPopup = new PopupWindow(v);
    mUndoPopup.setAnimationStyle(R.style.fade_animation);
    // Get scren width in dp and set width respectively
    int xdensity = (int)(mListView.getContext().getResources().getDisplayMetrics().widthPixels / mDensity);
    if(xdensity < 300) {
        mUndoPopup.setWidth((int)(mDensity * 280));
    } else if(xdensity < 350) {
        mUndoPopup.setWidth((int)(mDensity * 300));
    } else if(xdensity < 500) {
        mUndoPopup.setWidth((int)(mDensity * 330));
    } else {
        mUndoPopup.setWidth((int)(mDensity * 450));
    }
    mUndoPopup.setHeight((int)(mDensity * 56));
    // -- END Load undo popu --

    listView.setOnTouchListener(this);
    listView.setOnScrollListener(this.makeScrollListener());

    switch(mode) {
        case SINGLE_UNDO:
            mUndoActions = new ArrayList<Undoable>(1);
            break;
        default:
            mUndoActions = new ArrayList<Undoable>(10);
            break;
    }

}


private void setEnabled(boolean enabled) {
    mPaused = !enabled;
}

public void setAutoHideDelay(int delay) {
    mAutoHideDelay = delay;
}


public void setSwipeDirection(SwipeDirection direction) {
    mSwipeDirection = direction;
}


public void setUndoString(String msg) {
    mDeleteString = msg;
}


public void setUndoMultipleString(String msg) {
    mDeleteMultipleString = msg;
}


public void setRequireTouchBeforeDismiss(boolean require) {
    mTouchBeforeAutoHide = require;
}


public void discardUndo() {
    for(Undoable undoable : mUndoActions) {
        undoable.discard();
    }
    mUndoActions.clear();
    mUndoPopup.dismiss();
}


private AbsListView.OnScrollListener makeScrollListener() {
    return new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int scrollState) {
            setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
        }

        @Override
        public void onScroll(AbsListView absListView, int i, int i1, int i2) {
        }
    };
}

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    if (this.mSwipeDisabled) {
        return false;
    }

    if (mViewWidth < 2) {
        mViewWidth = mListView.getWidth();
    }

    switch (motionEvent.getActionMasked()) {
        case MotionEvent.ACTION_DOWN: {
            if (mPaused) {
                return false;
            }

            // TODO: ensure this is a finger, and set a flag

            // Find the child view that was touched (perform a hit test)
            Rect rect = new Rect();
            int childCount = mListView.getChildCount();
            int[] listViewCoords = new int[2];
            mListView.getLocationOnScreen(listViewCoords);
            int x = (int) motionEvent.getRawX() - listViewCoords[0];
            int y = (int) motionEvent.getRawY() - listViewCoords[1];
            View child;
            for (int i = 0; i < childCount; i++) {
                child = mListView.getChildAt(i);
                child.getHitRect(rect);
                if (rect.contains(x, y)) {
                    mDownView = child;
                    break;
                }
            }

            if (mDownView != null) {
                mDownX = motionEvent.getRawX();
                mDownPosition = mListView.getPositionForView(mDownView);

                mVelocityTracker = VelocityTracker.obtain();
                mVelocityTracker.addMovement(motionEvent);
            }
            view.onTouchEvent(motionEvent);
            return true;
        }

        case MotionEvent.ACTION_UP: {
            if (mVelocityTracker == null) {
                break;
            }

            float deltaX = motionEvent.getRawX() - mDownX;
            mVelocityTracker.addMovement(motionEvent);
            mVelocityTracker.computeCurrentVelocity(1000);
            float velocityX = Math.abs(mVelocityTracker.getXVelocity());
            float velocityY = Math.abs(mVelocityTracker.getYVelocity());
            boolean dismiss = false;
            boolean dismissRight = false;
            if (Math.abs(deltaX) > mViewWidth / 2 && mSwiping) {
                dismiss = true;
                dismissRight = deltaX > 0;
            } else if (mMinFlingVelocity <= velocityX && velocityX <= mMaxFlingVelocity
                && velocityY < velocityX && mSwiping && isDirectionValid(mVelocityTracker.getXVelocity())
                && deltaX >= mViewWidth * 0.2f) {
                dismiss = true;
                dismissRight = mVelocityTracker.getXVelocity() > 0;
            }
            if (dismiss) {
                // dismiss
                final View downView = frontView; // mDownView gets null'd before animation ends
                final int downPosition = mDownPosition;
                ++mDismissAnimationRefCount;
                animate(frontView)
                    .translationX(dismissRight ? mViewWidth : -mViewWidth)
                    .alpha(0)
                    .setDuration(mAnimationTime)
                    .setListener(new AnimatorListenerAdapter() {
                    @Override 
                    public void onAnimationEnd(Animator animation) {
                        performDismiss(downView, downPosition);
                    }
                });
            } else {
                // cancel
                animate(frontView)
                    .translationX(0)
                    .alpha(1)
                    .setDuration(mAnimationTime)
                    .setListener(null);
            }
            mVelocityTracker = null;
            mDownX = 0;
            mDownView = null;
            mDownPosition = ListView.INVALID_POSITION;
            mSwiping = false;

            if(backView != null) {
                backView.setVisibility(View.GONE);
                frontView.setVisibility(View.VISIBLE);
                setTranslationX(frontView, 0);

                layout = null;
                backView = null;
                frontView = null;
            }
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            if(mTouchBeforeAutoHide && mUndoPopup.isShowing()) {    
                // Send a delayed message to hide popup
                mHandler.sendMessageDelayed(mHandler.obtainMessage(mDelayedMsgId), 
                    mAutoHideDelay);
            }

            if (mVelocityTracker == null || mPaused) {
                break;
            }

            mVelocityTracker.addMovement(motionEvent);
            float deltaX = motionEvent.getRawX() - mDownX;
            // Only start swipe in correct direction
            if(isDirectionValid(deltaX)) {
                if (Math.abs(deltaX) > mSlop) {
                    mSwiping = true;
                    mListView.requestDisallowInterceptTouchEvent(true);

                    // Cancel ListView's touch (un-highlighting the item)
                    MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL
                        | (motionEvent.getActionIndex()
                        << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
                    mListView.onTouchEvent(cancelEvent);
                }
            } else {
                mDownX = motionEvent.getRawX();
                deltaX = 0;
            }

            if(layout == null) {
                layout = (RelativeLayout) mDownView;
                frontView = layout.getChildAt(0);
                backView = layout.getChildAt(1);
            }

            if(deltaX > 50) {
                backView.setVisibility(View.VISIBLE);
            }

            if (mSwiping) {
                setTranslationX(frontView, deltaX);
                setAlpha(frontView, Math.max(0f, Math.min(1f,
                    1f - 2f * Math.abs(deltaX) / mViewWidth)));
                return true;
            }
            break;
        }
    }
    return false;
}


private boolean isDirectionValid(float deltaX) {

    int rtlSign = 1;
    // On API level 17 and above, check if we are in a Right-To-Left layout
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        if(mListView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
            rtlSign = -1;
        }
    }

    // Check if swipe has been done in the corret direction
    switch(mSwipeDirection) {
        default:
        case BOTH:
            return true;
        case START:
            return rtlSign * deltaX < 0;
        case END:
            return rtlSign * deltaX > 0;
    }

}

class PendingDismissData implements Comparable<PendingDismissData> {

    public int position;
    public View view;

    public PendingDismissData(int position, View view) {
        this.position = position;
        this.view = view;
    }

    @Override
    public int compareTo(PendingDismissData other) {
        // Sort by descending position
        return other.position - position;
    }
}

private void performDismiss(final View dismissView, final int dismissPosition) {
    // Animate the dismissed list item to zero-height and fire the dismiss callback when
    // all dismissed list item animations have completed. This triggers layout on each animation
    // frame; in the future we may want to do something smarter and more performant.

    final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
    final int originalHeight = dismissView.getHeight();

    ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);

    animator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            --mDismissAnimationRefCount;
            if (mDismissAnimationRefCount == 0) {
                // No active animations, process all pending dismisses.

                for(PendingDismissData dismiss : mPendingDismisses) {
                    if(mMode == UndoMode.SINGLE_UNDO) {
                        for(Undoable undoable : mUndoActions) {
                            undoable.discard();
                        }
                        mUndoActions.clear();
                    }
                    Undoable undoable = mCallback.onDismiss(mListView, dismiss.position);
                    if(undoable != null) {
                        mUndoActions.add(undoable);
                    }
                    mDelayedMsgId++;
                }

                if(!mUndoActions.isEmpty()) {
                    changePopupText();
                    changeButtonLabel();

                    // Show undo popup
                    mUndoPopup.showAtLocation(mListView, 
                        Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
                        0, (int)(mDensity * 15));

                    // Queue the dismiss only if required
                    if(!mTouchBeforeAutoHide) { 
                        // Send a delayed message to hide popup
                        mHandler.sendMessageDelayed(mHandler.obtainMessage(mDelayedMsgId), 
                            mAutoHideDelay);
                    }
                }

                ViewGroup.LayoutParams lp;
                for (PendingDismissData pendingDismiss : mPendingDismisses) {
                    // Reset view presentation
                    setAlpha(pendingDismiss.view, 1f);
                    setTranslationX(pendingDismiss.view, 0);
                    lp = pendingDismiss.view.getLayoutParams();
                    lp.height = originalHeight;
                    pendingDismiss.view.setLayoutParams(lp);
                }

                mPendingDismisses.clear();
            }
        }
    });

    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            lp.height = (Integer) valueAnimator.getAnimatedValue();
            dismissView.setLayoutParams(lp);
        }
    });

    mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView));
    animator.start();
}


private void changePopupText() {
    String msg = "";
    if(mUndoActions.size() > 1 && mDeleteMultipleString != null) {
        msg = String.format(mDeleteMultipleString, mUndoActions.size());
    } else if(mUndoActions.size() >= 1) {
        // Set title from single undoable or when no multiple deletion string
        // is given
        if(mUndoActions.get(mUndoActions.size() - 1).getTitle() != null) {
            msg = mUndoActions.get(mUndoActions.size() - 1).getTitle();
        } else {
            msg = mDeleteString;
        }
    }
    mUndoText.setText(msg);
}

private void changeButtonLabel() {
    String msg;
    if(mUndoActions.size() > 1 && mMode == UndoMode.COLLAPSED_UNDO) {
        msg = mListView.getResources().getString(R.string.undoall);
    } else {
        msg = mListView.getResources().getString(R.string.undo);
    }
    mUndoButton.setText(msg);
}

/**
 * Takes care of undoing a dismiss. This will be added as a 
 * {@link View.OnClickListener} to the undo button in the undo popup.
 */
private class UndoHandler implements View.OnClickListener {

    public void onClick(View v) {
        if(!mUndoActions.isEmpty()) {
            switch(mMode) {
                case SINGLE_UNDO:
                    mUndoActions.get(0).undo();
                    mUndoActions.clear();
                    break;
                case COLLAPSED_UNDO:
                    Collections.reverse(mUndoActions);
                    for(Undoable undo : mUndoActions) {
                        undo.undo();    
                    }
                    mUndoActions.clear();
                    break;
                case MULTI_UNDO:
                    mUndoActions.get(mUndoActions.size() - 1).undo();
                    mUndoActions.remove(mUndoActions.size() - 1);
                    break;
            }
        }

        // Dismiss dialog or change text
        if(mUndoActions.isEmpty()) {
            mUndoPopup.dismiss();
        } else {
            changePopupText();
            changeButtonLabel();
        }

        mDelayedMsgId++;

    }

}

/**
 * Handler used to hide the undo popup after a special delay.
 */
private class HideUndoPopupHandler extends Handler {

    @Override
    public void handleMessage(Message msg) {
        if(msg.what == mDelayedMsgId) {
            // Call discard on any element
            for(Undoable undo : mUndoActions) {
                undo.discard();
            }
            mUndoActions.clear();
            mUndoPopup.dismiss();
        }
    }

}

/**
 * Enable/disable swipe.
 */
public void setSwipeDisabled(boolean disabled) {
    this.mSwipeDisabled = disabled;
}
  }

尽情享受吧!

关于android - 在 ListView 中实现滑动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17019359/

有关android - 在 ListView 中实现滑动的更多相关文章

  1. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  2. ruby-on-rails - 如何在 Ruby on Rails 中实现无向图? - 2

    我需要在RubyonRails中实现无向图G=(V,E)并考虑构建一个Vertex和一个Edge模型,其中Vertex有_多条边。由于边恰好连接两个顶点,您将如何在Rails中执行此操作?您是否知道任何有助于实现此类图表的gem或库(对重新发明轮子不感兴趣;-))? 最佳答案 不知道有任何现有库在ActiveRecord之上提供图形逻辑。您可能必须实现自己的Vertex、EdgeActiveRecord支持的模型(请参阅Rails安装的rails/activerecord中的vertex.rb和edge.rb/test/fixtur

  3. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  4. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  5. ruby - 在 Ruby 中实现 to_int 和 to_str 的后果 - 2

    我haveaclass它公开了一个字符串值和一个int值(分别是命令输出和退出代码)。除了通过to_s和to_i公开它们之外,我还使用to_str和to_int,如下所示:classStatusdefto_s@outputendalias:to_str:to_sdefto_i@status.exitstatusendalias:to_int:to_iend我的想法是能够在尽可能多的情况下使用这个对象。将其强制转换为字符串或整数会增加可用性。例如,我可以将对象与字符串连接起来:a_string="Outputwas:"+results(我想用这个作为int强制转换的例子,但是Fixnum

  6. ruby - 在 Ruby 中实现二叉树 - 2

    我一直在尝试在Ruby中实现BinaryTree类,但我得到了stackleveltoodeep错误,尽管我似乎没有在该特定代码段中使用任何递归:1.classBinaryTree2.includeEnumerable3.4.attr_accessor:value5.6.definitialize(value=nil)7.@value=value8.@left=BinaryTree.new#stackleveltoodeephere9.@right=BinaryTree.new#andhere10.end11.12.defempty?13.(self.value==nil)?true:

  7. ruby - 如何在 Ruby 中实现私有(private)内部类 - 2

    来自Java,我正在尝试在Ruby中实现LinkedList。我在Java中实现它的通常方法是有一个名为LinkedList的类和一个名为Node的私有(private)内部类,其中LinkedList的每个对象都作为Node对象。classLinkedListprivateclassNodeattr_accessor:val,:nextendend我不想将Node类暴露给外部世界。然而,通过Ruby中的这个设置,我可以使用这个访问LinkedList类之外的私有(private)Node类对象-node=LinkedList::Node.new我知道,在Ruby1.9中,我们可以使用

  8. ruby - 在 Ruby 中实现 Luhn 算法 - 2

    我一直在尝试用Ruby实现Luhn算法。我一直在执行以下步骤:该公式根据其包含的校验位验证数字,该校验位通常附加到部分帐号以生成完整帐号。此帐号必须通过以下测试:从最右边的校验位开始向左移动,每第二个数字的值加倍。将乘积的数字(例如,10=1+0=1、14=1+4=5)与原始数字的未加倍数字相加。如果总模10等于0(如果总和以零结尾),则根据Luhn公式该数字有效;否则无效。http://en.wikipedia.org/wiki/Luhn_algorithm这是我想出的:defvalidCreditCard(cardNumber)sum=0nums=cardNumber.to_s.s

  9. ruby - 在 Ruby 中实现生产者消费者模式 - 2

    假设我有200个昂贵的方法调用(每个都有不同的参数)。出于某种原因,我可以并行执行其中的5个调用,但不能更多。我可以一次执行一个,但一次执行5个要快5倍。我想一直执行五件事。不想排五个,等五个都排完了,再排五个。如果我排队A、B、C、D、E并且C先完成,我想立即用F替换它,即使A和B还没有完成。我一直在研究这个问题,因为我可以想象它会定期发生。解决方案似乎是生产者-消费者模式,Ruby在其标准库中内置了一些用于该模式的结构(Queue和SizedQueue)。我玩过代码示例,阅读了一些文档,我想我对它有一个粗略的了解。但是我有一些问题我对我的解决方案没有信心,而且多线程的整个领域对我来

  10. ruby - 如何在 Ruby 中实现枚举器? - 2

    例如:a=[1,2,3,4,5]a.delete_if{|x|x>3}相当于:a=[1,2,3,4,5]a.delete_if.each.each.each.each{|x|x>3}我知道a.delete_if返回一个枚举器。但是当eachblock返回true时,它​​如何知道应该删除对象呢?如何手动(和在Ruby中)实现delete_if? 最佳答案 可以看看Rubinius源码:enumerablemodule这里是一个拒绝方法的例子:defrejectreturnto_enum(:reject)unlessblock_giv

随机推荐