Nano Hash - криптовалюты, майнинг, программирование

Проблема с большими изображениями внутри галереи

Я пытаюсь создать горизонтальную скользящую сетку изображения. Я использую представление галереи с адаптером, предоставляющим мне TableLayouts, содержащие изображения для отображения. Все выглядит нормально, но когда я касаюсь экрана (MotionEvent.ACTION_DOWN), галерея резко перемещается влево или вправо, что затрудняет пролистывание (текущий отображаемый дочерний элемент перемещается вперед). Любая подсказка о том, как это исправить? Это лучший подход?

Изменить: здесь исходный код

import java.util.LinkedList;
import java.util.WeakHashMap;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.SpinnerAdapter;
import android.widget.TableLayout;
import android.widget.TableRow;
public class Dock extends Gallery {
private Adapter mAdapter;
private int numLines=1;
private int numColumns=1;
protected int columnWidth = GridView.AUTO_FIT;
private OnItemClickListener myOnItemClickListener;
private OnItemLongClickListener myOnItemLongClickListener;
private OnItemSelectedListener myOnItemSelectedClickListener;
private GestureDetector interceptGest = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener(){
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return true;
    };
});
public int columnSpacing = 10;
private CustomAdapter adapt;
public Dock(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initDock();
}
public Dock(Context context, AttributeSet attrs) {
    super(context, attrs);
    initDock();
}
public Dock(Context context) {
    super(context);
    initDock();
}
private void initDock(){
    this.setSpacing(50);
    this.setHorizontalFadingEdgeEnabled(false);
    this.setGravity(Gravity.CENTER);
    this.setBackgroundColor(Color.GREEN);
    this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
public int getNumLines() {
    return numLines;
}
public void setNumLines(int numLines) {
    this.numLines = numLines;
}
public int getNumColumns() {
    return numColumns;
}
public void setNumColumns(int numColumns) {
    this.numColumns = numColumns;
}
public void setOnItemClickListener(
        android.widget.AdapterView.OnItemClickListener listener) {
    this.myOnItemClickListener = listener;
}

public void setOnItemLongClickListener(
        android.widget.AdapterView.OnItemLongClickListener listener) {
    this.myOnItemLongClickListener = listener;
}
public void setOnItemSelectedListener(
        android.widget.AdapterView.OnItemSelectedListener listener) {
    this.myOnItemSelectedClickListener = listener;
}
public void setAdapter(final SpinnerAdapter adapter) {
    adapt = new CustomAdapter(adapter);
    mAdapter = adapter;
    super.setAdapter(adapt);
}

@Override
public SpinnerAdapter getAdapter() {
    return (SpinnerAdapter) mAdapter;
}
private class CustomGrid extends TableLayout{
    private AdapterView<Adapter> mAdapterView = new AdapterView<Adapter>(getContext()){
        @Override
        public Adapter getAdapter() {
            return mAdapter;
        }
        @Override
        public View getSelectedView() {
            return Dock.this.findFocus();
        }
        @Override
        public void setAdapter(Adapter adapter) {
            Dock.this.setAdapter((SpinnerAdapter) adapter);
        }
        @Override
        public void setSelection(int position) {
            Dock.this.setSelection(position);
        }
    };
    private int page;
    private Adapter adapter;
    protected android.widget.AdapterView.OnItemClickListener mOnItemClickListener;
    protected android.widget.AdapterView.OnItemLongClickListener mOnItemLongClickListener;
    protected android.widget.AdapterView.OnItemSelectedListener mOnItemSelectedListener;
    public CustomGrid(Context context, AttributeSet attrs) {
        super(context, attrs);
        initGrid();
    }
    public CustomGrid(Context context) {
        super(context);
        initGrid();
    }
    private void initGrid(){
        this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
        this.setFocusable(false);
    }
    public void setPage(int position) {
        this.page = position;
    }
    public void setAdapter(BaseAdapter adapter) {
        this.adapter = adapter;
    }
    public void setOnItemClickListener(
            android.widget.AdapterView.OnItemClickListener onItemClickListener) {
        this.mOnItemClickListener = onItemClickListener;
    }
    public void setOnItemLongClickListener(
            android.widget.AdapterView.OnItemLongClickListener onItemLongClickListener) {
        this.mOnItemLongClickListener = onItemLongClickListener;
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean ret = false;
        if(ev.getAction()==MotionEvent.ACTION_MOVE)
            ret = true;
        else
            ret = super.onInterceptTouchEvent(ev);
        return ret;
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if(ev.getAction()==MotionEvent.ACTION_MOVE)
            return false;
        else
            return super.onTouchEvent(ev);
    }
    public void setOnItemSelectedListener(
            android.widget.AdapterView.OnItemSelectedListener onItemSelectedListener) {
        this.mOnItemSelectedListener = onItemSelectedListener;
    }
    private View getCachedView(int position, ViewGroup parent) {
        int p = position + page*getNumColumns()*getNumLines();
        if(p<adapter.getCount())
            return adapter.getView(p, null, parent);
        else 
            return null;
    }
    private void refreshGrid(){
        if(mAdapter==null)
            return;
        int count=0;
        if(numLines>1)
            this.setPadding(5, 0, 5, 0);
        TableRow line = null;
        View view = null;
        for(int i = 0; i<numLines; i++){
            line = new TableRow(getContext());
            line.setBaselineAligned(false);
            line.setGravity(Gravity.CENTER);
            line.setFocusable(false);
            for(int j = 0; j< numColumns; j++){
                this.setColumnShrinkable(j, true);
                this.setColumnStretchable(j, true);
                view = getCachedView(count, line);
                if(view!=null){
                    final int position = count + page*getNumColumns()*getNumLines();
                    view.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View arg0) {
                            if(mOnItemClickListener!=null)
                                mOnItemClickListener.onItemClick(mAdapterView, arg0, position, mAdapter.getItemId(position));
                        }
                    });
                    view.setOnLongClickListener( new OnLongClickListener() {
                        @Override
                        public boolean onLongClick(View arg0) {
                            if(mOnItemLongClickListener!=null)
                                return mOnItemLongClickListener.onItemLongClick(mAdapterView, arg0, position, mAdapter.getItemId(position));
                            else return false;
                        }
                    });
                    view.setOnFocusChangeListener(new OnFocusChangeListener() {
                        @Override
                        public void onFocusChange(View arg0, boolean arg1) {
                            if(mOnItemSelectedListener!=null&&arg1){
                                mOnItemSelectedListener.onItemSelected(mAdapterView, arg0, position, mAdapter.getItemId(position));
                            }
                        }
                    });
                    view.setFocusable(false);
                    line.addView(view);
                }
                count++;
            }
            if(numLines>1)
                while(line.getChildCount()<numColumns){
                    View v = this.getEmptyView();
                    v.setFocusable(false);
                    line.addView(v);
                }
            this.addView(line);
        }
    }
    private View getEmptyView() {
        ImageView ret = new ImageView(getContext());
        ret.setBackgroundColor(Color.TRANSPARENT);
        return ret;
    }
}
private class CustomAdapter extends BaseAdapter{
    private WeakHashMap<Integer,CustomGrid> cache = new WeakHashMap<Integer,CustomGrid>();
    private LinkedList<Integer> cacheId = new LinkedList<Integer>();
    private Adapter adapter;
    public CustomAdapter(Adapter a){
        super();
        adapter = a;
    }
    public long getItemId(int position) {
        return position;
    }
    public Object getItem(int position) {
        return null;
    }
    public int getCount() {
        int n = adapter.getCount()/(numColumns*numLines);
        if(adapter.getCount()%(numColumns*numLines)!=0)
            n++;
        return n;
    }
    private CustomGrid getPage(final int position){
        CustomGrid ret = new CustomGrid(getContext());
        ret.setPage(position);
        ret.setAdapter((BaseAdapter) adapter);
        ret.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> adapterV, View v,
                    int pos, long id) {
                //int page = position;
                if(myOnItemClickListener!=null){
                    myOnItemClickListener.onItemClick(adapterV, v, pos, adapter.getItemId(pos));
                }
            }
        });
        ret.setOnItemLongClickListener(new OnItemLongClickListener() {
            public boolean onItemLongClick(AdapterView<?> adapterV,
                    View arg1, int pos, long arg3) {
                //int page = position;
                if(myOnItemLongClickListener!=null){
                    return myOnItemLongClickListener.onItemLongClick(adapterV, arg1, pos, adapter.getItemId(pos));
                }
                else
                    return false;
            }
        });
        ret.setOnItemSelectedListener(new OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> adapterV,
                    View arg1, int pos, long arg3) {
                if(myOnItemSelectedClickListener!=null){
                    myOnItemSelectedClickListener.onItemSelected(adapterV, arg1, pos, adapter.getItemId(pos));
                }
            }
            public void onNothingSelected(AdapterView<?> arg0) {
                if(myOnItemSelectedClickListener!=null)
                    myOnItemSelectedClickListener.onNothingSelected(arg0);
            }
        });
        ret.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        ret.setGravity(Gravity.CENTER);
        ret.setBackgroundColor(Color.BLUE);
        ret.refreshGrid();
        return ret;
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = cache.get(position);
        if(convertView==null){
            convertView = getPage(position);
            while(cache.size()>3){
                cache.remove(cacheId.removeFirst());
            }
            cache.put(position, (CustomGrid) convertView);
            cacheId.add(position);
            if(position<getCount()){
                cache.put(position+1, getPage(position+1));
                cacheId.add(position+1);
            }
        }
        return convertView;
    }
    public void flush() {
        cache.clear();
        cacheId.clear();
    }
};
public void setColumnWidth(int width) {
    this.columnWidth = width;
}
public void setColumnMargin(int margin){
    this.columnSpacing = margin;
}
private MotionEvent primTouch;
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) {
    if(e1!=null&&e2!=null){
        float dist = e1.getX()-e2.getX();
        if(Math.abs(dist)>30){
            if(dist>0)
                return onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT));
            else
                return onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT));
        }
    }
    return true;
}
private MotionEvent interm;
private boolean scrollingHorizontally=false;


public void flush(){
    adapt.flush();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if(ev.getAction()==MotionEvent.ACTION_DOWN)
        primTouch = ev;
    if(ev.getAction()==MotionEvent.ACTION_MOVE)
        return true;
    else
        return scrollingHorizontally;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    scrollingHorizontally = true;
    return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch(event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        primTouch=event;
        return super.onTouchEvent(event);
    case MotionEvent.ACTION_MOVE:
        scrollingHorizontally=true;
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        scrollingHorizontally = false;
        if(primTouch!=null){
            float dist = primTouch.getX()-event.getX();
            if(Math.abs(dist)>30){
                if(dist>0)
                    return onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT));
                else
                    return onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT));
            }
        }
        break;
    }
    return super.onTouchEvent(event);
}
 }

РЕДАКТИРОВАТЬ 2: я понял, что если я обрабатываю все сенсорные события в функции onInterceptTouchEvent(MotionEvent ev) (когда я устанавливаю, чтобы она всегда возвращала true), проблема исчезает, но любой onClickListener, установленный для дочернего элемента, отключен. Будет хорошо, если вы используете onItemClickListener или если вы точно знаете дочернюю структуру для отправки обнаруженного клика.


  • вы должны добавить свой код для справки. 19.08.2011

Ответы:


Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..