我有一个3x3网格视图。想象一下如下。
1 2 3
4 5 6
7 8 9
现在我想实现什么
我希望网格视图列在触摸时向上和向下移动。
考虑网格视图的第一列。那是
1
4
7
现在,如果我触摸此列的任何位置,可以在1或4或7上触摸,然后向上或向下滑动任何一个方向。然后我想将列移动1或2个位置。
让我明确一下
如果我通过触摸7向上滑动它应该会产生这样的结果
1
4 2 3
7 5 6
8 9
或者,如果我触摸第二列并向下移动它,那么它将看起来像下面的
1 3
4 2 6
7 5 9
8
如果我移动2个网格单元格的列,那么它将看起来像
1 3
4 6
7 2 9
5
8
对于每一列,我应该能够将列移动一个或两个单元格,具体取决于我滚动列的数量。
还有一件事如果我滚动列很少,如果它不是完全适合任何网格单元到所需位置那么它应该自动适合接近适合位置的网格单元。
我在这里搜索了太多关于堆栈溢出的问题并查询了一个google批次。但我没有得到我想要的东西。
如果我没有好好解释那么告诉我。我会尝试解释更多。 任何想法,任何暗示或任何技巧都会令人感激。
修改
如果我移动色谱柱超过3个网格然后释放触摸,则色谱柱将转换为仅两个元素。就像这样
1 3
4 6
7 2 9
5
8
任何开始的想法都会很明显
由于
答案 0 :(得分:6)
To do what you ask would require you to take charge of the GridView
's canvas, section off the column being touched and doing your own drawing for the drag, fling, etc. Once the movement is complete, you will need to make adjustments to the views in the column through the GridView
to keep the bookkeeping straight. I would look at on-line documentation that discusses view movement. "Dragging and Scaling" would be a good place to start.
There are going to be some "gotchas" in this approach. If you are just trying to learn this as a technique then I would say that your approach is OK. If you want to accomplish the effect and use the underlying implementation of GridView
as designed (scrolling, edge effects, flings, etc.), I suggest another approach.
Instead of a single 3x3 GridView
you could build up a semblance of the GridView
by aligning three 1x3 grid views side by side. (Really the grid views will be 1x11 to accommodate the maximum extent of the vertical slides.) Each grid view could be backed by a single adapter if coded to support multiple grid views. Since each column is its own grid view, each column can slide independently of the others.
The advantage of this approach is that you get the effect that you want without contorting the underlying GridView
class. This same approach can use your existing method that uses a button.
I hope this is helpful to you.
I was curious about what it would take to implement my suggestion. Below is a sample app with the three GridView
implementation as explained above and a video of the same.
MainActivity.java
public class MainActivity extends AppCompatActivity
implements GridView.OnScrollListener {
@Override
public void onCreate(Bundle savedInstanceState) {
final GridViewAdapter adapter = new GridViewAdapter();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupGridView(R.id.gridview0, adapter);
setupGridView(R.id.gridview1, adapter);
setupGridView(R.id.gridview2, adapter);
}
private void setupGridView(int id, GridViewAdapter adapter) {
final GridView gridview = (GridView) findViewById(id);
gridview.setAdapter(adapter);
// Temporary scroll listener until initial scroll to position is done.
// This hides the initial movement of the grid cells.
gridview.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
gridview.setOnScrollListener(MainActivity.this);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// Do nothing
}
});
gridview.smoothScrollToPositionFromTop(2, 0);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
final int top = view.getChildAt(0).getTop();
final int itemHeight = ((GridViewAdapter) (view.getAdapter())).getItemHeight();
// top <= 0
if (top > -(itemHeight / 2)) {
// Less than 1/2 cell height out of place - shift down.
view.scrollListBy(top);
} else {
// Shift up
view.scrollListBy(top + itemHeight);
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// Do nothing
}
@SuppressWarnings("unused")
private static final String TAG = "MainActivity";
}
GridViewAdapter.java
class GridViewAdapter extends BaseAdapter {
GridViewAdapter() {
}
@Override
public int getCount() {
return mStrings.length / GRID_COLUMN_COUNT;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
// create a new TextView for each item referenced by the Adapter
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView;
final int column = Integer.parseInt((String) parent.getTag());
if (convertView == null) {
// if it's not recycled, initialize some attributes
textView = new TextView(parent.getContext());
GridView.LayoutParams params =
new GridView.LayoutParams(GRID_ITEM_WIDTH, GRID_ITEM_HEIGHT);
textView.setLayoutParams(params);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
textView.setGravity(Gravity.CENTER);
} else {
// Recycle the view but keep old attributes since they don't change.
textView = (TextView) convertView;
}
textView.setText(mStrings[position * GRID_COLUMN_COUNT + column]);
return textView;
}
int getItemHeight() {
return GRID_ITEM_HEIGHT;
}
private final static String[] mStrings = {
"", "", "",
"", "", "",
"", "", "",
"", "", "",
"1", "2", "3",
"4", "5", "6",
"7", "8", "9",
"", "", "",
"", "", "",
"", "", "",
"", "", ""
};
private static final int GRID_ITEM_HEIGHT = 150; // in pixels
private static final int GRID_ITEM_WIDTH = 150; // in pixels
private static final int GRID_COLUMN_COUNT = 3;
}
activity_main.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<!-- Sorry for the dimensions in pixels. It just makes everything easier.
Non-pixel dimensions (dp) should be used here and accommodations made in the code. -->
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview0"
android:layout_width="150px"
android:layout_height="1050px"
android:columnWidth="150px"
android:horizontalSpacing="0dp"
android:numColumns="1"
android:scrollbars="none"
android:tag="0"
android:verticalSpacing="0dp" />
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview1"
android:layout_width="150px"
android:layout_height="1050px"
android:columnWidth="150px"
android:horizontalSpacing="0dp"
android:numColumns="1"
android:scrollbars="none"
android:tag="1"
android:verticalSpacing="0dp" />
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview2"
android:layout_width="150px"
android:layout_height="1050px"
android:columnWidth="150px"
android:horizontalSpacing="0dp"
android:numColumns="1"
android:scrollbars="none"
android:tag="2"
android:verticalSpacing="0dp" />
</LinearLayout>
答案 1 :(得分:2)
如果我将列移动超过3个网格单元格,那么它将移动与否。如果它移动它移动了多少个细胞?
答案 2 :(得分:0)
我没有任何代码块,但我可以解释如何实现这样的任务
你需要创建一个像这样的空单元格的网格
ist - &gt; - - - - - - - - -
第二 - &gt; - - - - - - - - -
第3 - &gt; - - - - - - - - -
第4 - &gt; - - - 1 2 3 - - -
5 - &gt; - - - 4 5 6 - - -
6th - &gt; - - - 7 8 9 - - -
7th - &gt; - - - - - - - - -
8th - &gt; - - - - - - - - -
9th - &gt; - - - - - - - - -
现在在向上滑动时获取相同列的所有元素然后移动到上部
希望此答案完全满足您的要求