Search code examples
androidgridviewscrollhorizontal-scrollingvertical-scrolling

Horizontal and vertical scrolling GridView Android


I am creating a component using GridView to create a table like Excel. Here I create a 2x2 grid initially and later when the user clicks a button, extra row and column is added.

This is what I do to add a new column :-

int numColumns = GVParticipantTable.getNumColumns() + 1;
                double numRows = Math.ceil((double) GVParticipantTable.getCount() / (double) GVParticipantTable.getNumColumns());
                int totalItems = (int) numRows * numColumns;

                if (participantDataList.size() > 4)
                {
                    totalItems = totalItems - participantDataList.size();
                }
                for (int i = 0; i < totalItems; i++)
                {
                    participantDataList.add("");

                }

                GVParticipantTable.setNumColumns(numColumns);
                mAdapterParticipantTable.notifyDataSetChanged();

This works fine and adds an extra column. The issue is that when the column is added, the previous columns shrink to accommodate the new column making the columns look smaller each time a new column is added. I want to show only 2 columns on the screen at a time and later let the user scroll ahead horizontally to view more columns. Right now the grid can only scroll vertically. Similarly I want this to happen when new rows are added, the user should be able to scroll vertically to see more rows.


Solution

  • As per what i know you should never use a HorizontalScrollView with a ListView, since ListView takes care of its own scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by HorizontalScrollView.

    http://developer.android.com/reference/android/widget/HorizontalScrollView.html
    

    Since you may be forced to use a two dimensional scrollview, you may consider using this: Internet archive of blog.gorges.us/2010/06/android-two-dimensional-scrollview/

    I haven't used this but it may be a reasonable approach.

    Maybe try By adding this in your XML file and in your JAVA

    <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
        android:id="@+id/scrollHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <ScrollView 
            android:id="@+id/scrollVertical"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" >
    
            //WateverViewYouWant
    
        </ScrollView>
    </HorizontalScrollView>
    

    And the code onCreate/onCreateView

    final HorizontalScrollView hScroll = (HorizontalScrollView) value.findViewById(R.id.scrollHorizontal);
        final ScrollView vScroll = (ScrollView) value.findViewById(R.id.scrollVertical);
        vScroll.setOnTouchListener(new View.OnTouchListener() { //inner scroll listener         
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return false;
            }
        });
        hScroll.setOnTouchListener(new View.OnTouchListener() { //outer scroll listener         
            private float mx, my, curX, curY;
            private boolean started = false;
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                curX = event.getX();
                curY = event.getY();
                int dx = (int) (mx - curX);
                int dy = (int) (my - curY);
                switch (event.getAction()) {
                    case MotionEvent.ACTION_MOVE:
                        if (started) {
                            vScroll.scrollBy(0, dy);
                            hScroll.scrollBy(dx, 0);
                        } else {
                            started = true;
                        }
                        mx = curX;
                        my = curY;
                        break;
                    case MotionEvent.ACTION_UP: 
                        vScroll.scrollBy(0, dy);
                        hScroll.scrollBy(dx, 0);
                        started = false;
                        break;
                }
                return true;
            }
        });