Ответ 1
Решение на самом деле довольно простое, но боль. Мне пришлось реализовать именно это в рамках программы, которую я недавно сделал. Однако есть несколько сложных вещей, которые вам нужно преодолеть. Следует отметить, что разные версии ОС имеют разные впечатления. Этот метод иногда отрицательно влияет на определенную специализацию или кладку, чтобы сделать эту работу как рисунок. Хотя I имеет рабочую копию, код, который я предоставляю, не для всех и зависит от любых других изменений или настроек в вашем коде.
- установите
android:layout_width
вwrap_content
- установите
android:layout_height
вwrap_content
- В вашем коде:
- определите, сколько строк у вас будет.
- разделите количество элементов на количество строк.
- добавить gridView.
setStretchMode(NO_STRETCH);
- добавить gridView.
setNumColumns(
количество столбцов);
- добавить gridView.
setColumnWidth(
явная ширина в пикселях);
- Прокрутить:
- Вы можете просто использовать gridView.
scrollBy()
вonTouchEvent()
- Вы можете просто использовать gridView.
Это шаги. Все они необходимы, чтобы заставить его работать. Ключ представляет собой NO_STRETCH с явным количеством столбцов с определенной шириной. Если вам требуется уточнение, можно предоставить дополнительную информацию. Вы можете даже использовать VelocityTracker или onFling для обработки flinging. У меня есть snappingToPage включен в мой. Используя это решение, даже не требуется переопределять onDraw()
или onLayout()
. Эти три строки кода избавляются от необходимости использования WebView или любого другого встраивания или вложения.
Двунаправленная прокрутка также довольно проста в применении. Вот простое решение для кода:
-
Во-первых, в вашем классе начните отслеживать позиции X и Y, создав два члена класса. Также добавьте отслеживание состояния;
// Holds the last position of the touch event (including movement) int myLastX; int myLastY; // Tracks the state of the Touch handling final static private int TOUCH_STATE_REST = 0; final static private int TOUCH_STATE_SCROLLING = 1; int myState = TOUCH_STATE_REST;
-
Во-вторых, убедитесь, что вы проверяете прокрутку, таким образом вы можете щелкнуть или долго щелкнуть сами изображения.
@Override public boolean onInterceptTouchEvent(final MotionEvent ev) {//User is already scrolling something. If we haven't interrupted this already, // then something else is handling its own scrolling and we should let this be. // Once we return TRUE, this event no longer fires and instead all goes to // onTouch() until the next TouchEvent begins (often beginning with ACTION_DOWN). if ((ev.getAction() == MotionEvent.ACTION_MOVE) && (myState != TOUCH_STATE_REST)) return false; // Grab the X and Y positions of the MotionEvent final float _x = ev.getX(); final float _y = ev.getY(); switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: final int _diffX = (int) Math.abs(_x - myLastX); final int _diffY = (int) Math.abs(_y - myLastY); final boolean xMoved = _diffX > 0; final boolean yMoved = _diffY > 0; if (xMoved || yMoved) myState = TOUCH_STATE_SCROLLING; break; case MotionEvent.ACTION_DOWN: // Remember location of down touch myLastX = _x; myLastY = _y; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (myState == TOUCH_STATE_SCROLLING) // Release the drag myState = TOUCH_STATE_REST; } //If we are not At Rest, start handling in our own onTouch() return myState != TOUCH_STATE_REST; }
-
После того, как GridView знает, что вы прокручиваете, он отправит все сенсорные события в onTouch. Сделайте свою прокрутку здесь.
@Override public boolean onTouchEvent(final MotionEvent ev) { final int action = ev.getAction(); final float x = ev.getX(); final float y = ev.getY(); final View child; switch (action) { case MotionEvent.ACTION_DOWN: //Supplemental code, if needed break; case MotionEvent.ACTION_MOVE: // This handles Scrolling only. if (myState == TOUCH_STATE_SCROLLING) { // Scroll to follow the motion event // This will update the vars as long as your finger is down. final int deltaX = (int) (myLastX - x); final int deltaY = (int) (myLastY - y); myLastX = x; myLastY = y; scrollBy(deltaX, deltaY); } break; case MotionEvent.ACTION_UP: // If Scrolling, stop the scroll so we can scroll later. if (myState == TOUCH_STATE_SCROLLING) myState = TOUCH_STATE_REST; break case MotionEvent.ACTION_CANCEL: // This is just a failsafe. I don't even know how to cancel a touch event myState = TOUCH_STATE_REST; } return true; }
Если курс, это решение перемещается в X и Y одновременно. Если вы хотите перемещать только одно направление за раз, вы можете легко отличить, проверив большую разницу X и Y. (т.е. Math.abs(deltaX) > Math.abs(deltaY)
) Ниже приведена частичная выборка для одной направленной прокрутки, но она может переключаться между X или Y.
3b. Измените это в OnTouch()
, если вы хотите обрабатывать одно направление за раз:
case MotionEvent.ACTION_MOVE:
if (myState == TOUCH_STATE_SCROLLING)
{
//This will update the vars as long as your finger is down.
final int deltaX = (int) (myLastX - x);
final int deltaY = (int) (myLastY - y);
myLastX = x;
myLastY = y;
// Check which direction is the bigger of the two
if (Math.abs(deltaX) > Math.abs(deltaY))
scrollBy(deltaX, 0);
else if (Math.abs(deltaY) > Math.abs(deltaX))
scrollBy(0, deltaY);
// We do nothing if they are equal.
}
break;
FuzzicalLogic