Элемент ListView LongClick для селектора - PullRequest
4 голосов
/ 22 января 2011

В ListViews по умолчанию, если вы долго нажимаете на элемент, фон исчезает от темно-синего до светло-синего (на Galaxy Tab. От оранжевого до светло-оранжевого на некоторых других устройствах) за время, необходимое для регистрации LongClick.Я предполагаю, что это делается каким-то образом с помощью селектора, но до сих пор я видел только то, как использовать селекторы для состояния: выбрано, состояния: сосредоточено и состояния: нажато.

Эта страница , похоже, не показывает ничего о состоянии LongClick, поэтому, возможно, мое предположение, что это выполняется с помощью селектора, неверно?

Может кто-нибудь сообщить мне, как по умолчанию ListView получает этот эффект и как я могу применить его к другим представлениям?

Ответы [ 3 ]

4 голосов
/ 27 января 2011

Так что это оказалось немного сложнее, чем я думал, но теперь он работает почти правильно.

Вот OnTouchListener, который я в итоге использовал:

listOnTouchListener = new OnTouchListener() {
         public boolean onTouch(View v, MotionEvent me){
             if (me.getAction() == MotionEvent.ACTION_DOWN){
                 //This means a finger has come down on top of our view
                 //We are going to start the animation now.
                 Log.i(myTag, "Action Down");
                 Context mContext = getApplicationContext();
                 Resources res = mContext.getResources();
                 TransitionDrawable transition = (TransitionDrawable) res.getDrawable(R.drawable.listtransition);
                 v.setBackgroundDrawable(transition);
                 //LongClick took approx. 510-530 milliseconds to register after OnTouch. So I set the duration at 500 millis.
                 transition.startTransition(500);
             }else if (me.getAction() == MotionEvent.ACTION_UP){
                 //This means we didn't hold long enough to get a LongClick
                 //Set the background back to the normal one.
                 v.setBackgroundResource(R.drawable.bubblelight);

             }else if (me.getAction() == MotionEvent.ACTION_MOVE){
                 //Do Nothing
             }else if (me.getAction() == MotionEvent.ACTION_CANCEL){
                 Log.i(myTag, "Action Cancel");
                 //This means we are scrolling on the list, not trying to longpress
                 //So set the background back to the normal one.
                 v.setBackgroundResource(R.drawable.bubblelight);
             }
             return false;

         }
     };

Я также использовал OnLongClickListener внутри этого, я установил фон обратно на нормальный.

Вот XML перехода:

<transition xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/bubblelight1" />
  <item android:drawable="@drawable/bubbledark" />
</transition>

Вы можете спросить, что с bubblelight1?Подробнее об этом чуть позже.

Вот метод getView (), который я использую внутри адаптера для возврата представлений, отображаемых в списке:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.row, null);
        }
        Status s = items.get(position);
        if (s != null) {
            v.setOnTouchListener(listOnTouchListener);
            v.setOnLongClickListener(listOnLongClickListener);
            tweetTxt = (TextView) v.findViewById(R.id.tweetTxt);
            timeTxt = (TextView) v.findViewById(R.id.timeTxt);
            if (tweetTxt != null) {
                tweetTxt.setText(s.getText());
                tweetTxt.setOnTouchListener(gestureListener);
            }
            if(timeTxt != null){
                timeTxt.setText(getTimeFromNow(s.getCreatedAt().getTime()));
                //timeTxt.setText(s.getCreatedAt().toLocaleString());
            }
        }
        LinkifyWithTwitter.addLinks(tweetTxt, Linkify.ALL);
        return v;
    }

v.setOnTouchListener (listOnTouchListener);и v.setOnLongClickListener (listOnLongClickListener);это линии, которые настраивают вид с помощью Слушателей, которые я показывал выше.

Теперь о bubblelight1.bubblelight и bubbledark - это девять патчей-изображений, которые я использую, когда я пробовал это в первый раз, когда начинался переход, а не фон, переходящий от пузырькового света к пузырьковому, пузырьковый свет становился больше, и пузырьковый дым появлялся внутри пузырькового света.Итак, у меня был большой светлый пузырь, маленький темный пузырь, а затем текст внутри него.Чтобы решить эту проблему, я сделал копию пузырькового света и полностью заправил нижний и правый края девятисекции. Мне просто нужно было сделать первое изображение при переходе, а не второе.Если бы я сделал второе изображение таким образом, мой текст выпрыгнул бы из пузыря, а некоторые из них были бы показаны сверху и по бокам пузыря.Я не совсем уверен, почему это происходило или почему это исправление сработало.Но это делает работу на данный момент.

1 голос
/ 22 января 2011

http://developer.android.com/guide/topics/ui/menus.html#context-menu

Когда пользователь выполняет длинное нажатие на элемент в ListView, и список регистрируется для предоставления контекстного меню, элемент списка сообщает пользователю, что контекстменю доступно путем анимации его цвета фона - оно переходит с оранжевого на белый перед открытием контекстного меню.(Приложение «Контакты» демонстрирует эту функцию.)

Так что это анимация, которая используется.Я полагаю, что для отображения он использует собственные методы View ... () по умолчанию.Возможно, вам придется позаботиться о предоставлении атрибутов clickable = "true" или longClickable = "true".

0 голосов
/ 12 февраля 2012

В дополнение к OnTouchListener вы можете использовать Runnable, чтобы вернуть фон в исходное состояние, чтобы вам не пришлось явно делать это в обработчике OnLongClick.

Handler myHandler = new Handler();
...
transition.startTransition(ViewConfiguration.getLongPressTimeout());
ResetBG r = new ResetBG(transition);
myHandler.postDelayed(r, ViewConfiguration.getLongPressTimeout());

где ResetBG:

class ResetBG implements Runnable {
    protected TransitionDrawable myTran;

    public Runnable(TransitionDrawable tran) {
        myTran = tran;
    }

    public void run() {
        myTran.resetTransition();
    }
}
...