Shift column of Gridview up and down on touch on that column
Asked Answered
P

3

7

I have a 3x3 grid view. Imagine like below.

1 2 3
4 5 6
7 8 9

NOW WHAT I WANT TO ACHIEVE

I want the column of grid view to shift upwards and downwards on touch.

Consider, the first column of a grid view. That is

1
4
7

Now, If I touch anywhere on this column, either on 1 or on 4 or on 7 and swipe in any one direction like upside or downside. Then I want to shift the column by 1 or 2 places.

Let me clear that

If I swipe towards upside by touch on 7. It should result like this

1
4 2 3
7 5 6 
  8 9

Or, If I touch the second column and move it in below direction then it will look like something below

1   3
4 2 6
7 5 9
  8

And If I move the column for 2 grid cells then it will look like

1   3
4   6
7 2 9
  5
  8

For every column, I should able to shift the column by one or two cell depending on how much I scroll the column.

One more thing If I scroll the column little and If it's not exactly fitting any grid cell to the desired position then It should automatically fit the grid cell that is close to fit the position.

I have search too many questions here on stack overflow and query a google lot. But I am not getting what I exactly want.

If I did not explain well then tell me. I will try to explain more. Any idea, any hint or any trick would be appreciable.

EDIT

If I move the column more than 3 grids then on releasing the touch, the column will shift to two elements only. Just like this

1   3
4   6
7 2 9
  5
  8
Pula answered 1/8, 2017 at 7:4 Comment(2)
Does it have to be a 3x3 GridView or could it be something else like 3 1x3 GridView's that each can scroll up and down? That would be easier to implement but may require more work behind the scenes.Divorcee
@Divorcee no gridview would be of any size. Here 3x3 is just an example i given to illustrate. And Yes I definitely know that it will require more work.Pula
D
7

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 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.

enter image description here

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>
Divorcee answered 4/8, 2017 at 12:43 Comment(0)
C
2

If I move the column for more than 3 grid cells then it will move or not. if it moves how many cells it moves ?

Countervail answered 1/8, 2017 at 7:26 Comment(2)
blahti.wordpress.com/2011/10/03/drag-drop-for-android-gridview Try this if not i can build the codeCountervail
i have checked an above link, but it just drag and drop one cell of the grid. But my requirement is a bit different. I want to move the particular column of a gridview on touch on that. Drag and Drop mechanism is somewhat different and I dont want that. By the way thanks for your effortPula
A
0

I don't have any code block but I can explain how you can achieve thus task

you need to create a grid with empty cells like this

1st -> - - - - - - - - -

2nd -> - - - - - - - - -

3rd -> - - - - - - - - -

4th -> - - - 1 2 3 - - -

5th -> - - - 4 5 6 - - -

6th -> - - - 7 8 9 - - -

7th -> - - - - - - - - -

8th -> - - - - - - - - -

9th -> - - - - - - - - -

now on swipe up get get all elements of same column and move then to upper

Aceae answered 4/8, 2017 at 7:56 Comment(2)
Yes. You are right. I should have to add an empty cell. And I actually did that. have put 2 arrow buttons to move a column downside and upside. Everything is working fine and exactly working as I want. But I want to implement a touch on grid column. Right now I am doing this on button click and now I want the same feature with touchPula
for swipe : #4139788Aceae

© 2022 - 2024 — McMap. All rights reserved.