最新回復
  • 5月前
    1 #

    我使用靜態陣列来驅動最大高度 行.這是不完美的,因為在重新顯示该單元格之前,不会調整前几列的大小.這是膨脹的可重用內容视圖的代碼。

    Edit :我正確地完成了這項工作,但是在渲染之前我已经預先測量了所有單元格.我是通過子類化GridView並在onLayout方法中添加一个測量钩子来實現的。

    /**
     * Custom view group that shares a common max height
     * @author Chase Colburn
     */
    public class GridViewItemLayout extends LinearLayout {
        // Array of max cell heights for each row
        private static int[] mMaxRowHeight;
        // The number of columns in the grid view
        private static int mNumColumns;
        // The position of the view cell
        private int mPosition;
        // Public constructor
        public GridViewItemLayout(Context context) {
            super(context);
        }
        // Public constructor
        public GridViewItemLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        /**
         * Set the position of the view cell
         * @param position
         */
        public void setPosition(int position) {
            mPosition = position;
        }
        /**
         * Set the number of columns and item count in order to accurately store the
         * max height for each row. This must be called whenever there is a change to the layout
         * or content data.
         * 
         * @param numColumns
         * @param itemCount
         */
        public static void initItemLayout(int numColumns, int itemCount) {
            mNumColumns = numColumns;
            mMaxRowHeight = new int[itemCount];
        }
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            // Do not calculate max height if column count is only one
            if(mNumColumns <= 1 || mMaxRowHeight == null) {
                return;
            }
            // Get the current view cell index for the grid row
            int rowIndex = mPosition / mNumColumns;
            // Get the measured height for this layout
            int measuredHeight = getMeasuredHeight();
            // If the current height is larger than previous measurements, update the array
            if(measuredHeight > mMaxRowHeight[rowIndex]) {
                mMaxRowHeight[rowIndex] = measuredHeight;
            }
            // Update the dimensions of the layout to reflect the max height
            setMeasuredDimension(getMeasuredWidth(), mMaxRowHeight[rowIndex]);
        }
    }
    

    這是我的BaseAdapter子類中的測量功能.請註意,我有一个方法 updateItemDisplay 在视圖單元格上設置所有適当的文字和圖像。

       /**
         * Run a pass through each item and force a measure to determine the max height for each row
         */
        public void measureItems(int columnWidth) {
            // Obtain system inflater
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            // Inflate temp layout object for measuring
            GridViewItemLayout itemView = (GridViewItemLayout)inflater.inflate(R.layout.list_confirm_item, null);
            // Create measuring specs
            int widthMeasureSpec = MeasureSpec.makeMeasureSpec(columnWidth, MeasureSpec.EXACTLY);
            int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            // Loop through each data object
            for(int index = 0; index < mItems.size(); index++) {
                String[] item = mItems.get(index);
                // Set position and data
                itemView.setPosition(index);
                itemView.updateItemDisplay(item, mLanguage);
                // Force measuring
                itemView.requestLayout();
                itemView.measure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    

    最後,這是GridView子類,用於在佈局期間測量视圖單元:

    /**
     * Custom subclass of grid view to measure all view cells
     * in order to determine the max height of the row
     * 
     * @author Chase Colburn
     */
    public class AutoMeasureGridView extends GridView {
        public AutoMeasureGridView(Context context) {
            super(context);
        }
        public AutoMeasureGridView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        public AutoMeasureGridView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            if(changed) {
                CustomAdapter adapter = (CustomAdapter)getAdapter();
                int numColumns = getContext().getResources().getInteger(R.integer.list_num_columns);
                GridViewItemLayout.initItemLayout(numColumns, adapter.getCount());
                if(numColumns > 1) {
                    int columnWidth = getMeasuredWidth() / numColumns;
                    adapter.measureItems(columnWidth);
                }
            }
            super.onLayout(changed, l, t, r, b);
        }
    }
    

    我將列數作為資源的原因是,以便可以根据方向等获得不同的列數。

  • 5月前
    2 #

    基於Chris的資訊,我使用了此變通方法 確定其他GridView項的高度時,本機GridView使用的引用视圖的大小。

    我建立了這个GridViewItemContainer自定義類:

    /**
     * This class makes sure that all items in a GridView row are of the same height.
     * (Could extend FrameLayout, LinearLayout etc as well, RelativeLayout was just my choice here)
     * @author Anton Spaans
     *
    */
    public class GridViewItemContainer extends RelativeLayout {
    private View[] viewsInRow;
    public GridViewItemContainer(Context context) {
        super(context);
    }
    public GridViewItemContainer(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    public GridViewItemContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setViewsInRow(View[] viewsInRow) {
        if  (viewsInRow != null) {
            if (this.viewsInRow == null) {
                this.viewsInRow = Arrays.copyOf(viewsInRow, viewsInRow.length);
            }
            else {
                System.arraycopy(viewsInRow, 0, this.viewsInRow, 0, viewsInRow.length);
            }
        }
        else if (this.viewsInRow != null){
            Arrays.fill(this.viewsInRow, null);
        }
    }
    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (viewsInRow == null) {
            return;
        }
        int measuredHeight = getMeasuredHeight();
        int maxHeight      = measuredHeight;
        for (View siblingInRow : viewsInRow) {
            if  (siblingInRow != null) {
                maxHeight = Math.max(maxHeight, siblingInRow.getMeasuredHeight());
            }
        }
        if (maxHeight == measuredHeight) {
            return;
        }
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        switch(heightMode) {
        case MeasureSpec.AT_MOST:
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(maxHeight, heightSize), MeasureSpec.EXACTLY);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            break;
        case MeasureSpec.EXACTLY:
            // No debate here. Final measuring already took place. That's it.
            break;
        case MeasureSpec.UNSPECIFIED:
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.EXACTLY);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            break;
        }
    }
    

    在適配器的getView方法中,將convertView作為子級包裝在新的GridViewItemContainer中,或使其成為專案佈局的頂部XML元素:

           // convertView has been just been inflated or came from getView parameter.
            if (!(convertView instanceof GridViewItemContainer)) {
                ViewGroup container = new GridViewItemContainer(inflater.getContext());
                // If you have tags, move them to the new top element. E.g.:
                container.setTag(convertView.getTag());
                convertView.setTag(null);
                container.addView(convertView);
                convertView = container;
            }
            ...
            ...
            viewsInRow[position % numColumns] = convertView;
            GridViewItemContainer referenceView = (GridViewItemContainer)convertView;
            if ((position % numColumns == (numColumns-1)) || (position == getCount()-1)) {
                referenceView.setViewsInRow(viewsInRow);
            }
            else {
                referenceView.setViewsInRow(null);
            }
    

    其中numColumns是GridView中的列數," viewsInRow"是"位置"所在当前行的View列表。

  • 5月前
    3 #

    我做了很多研究,但發現不完整 答案或很难理解解決方案的內容,但最终找到了一个正確解釋的答案。

    我的問题是正確地將gridview專案調整為高度.這个 Grid-view 当您所有视圖的高度相同時,效果很好.但是,当您的视圖具有不同的高度時,網格將無法達到預期的效果.视圖將彼此重叠,从而匯致 an-aesthetically 令人愉悦的網格。

    在此解決方案中,我在XML佈局中使用了此類。

    我使用了此解決方案,並且效果很好,非常感谢。--Abhishek Mittal

  • 5月前
    4 #

    如果將GridView或ListView轉換為RecyclerView,則不会發生此問题.而且,您無需建立自定義的GridView類。

  • 5月前
    5 #

    為GridView賦予權重也可以作為子元素在LinearLayouts內的GridView上使用.這樣,GridView会將子項填充到视口中,因此只要它们適合螢幕,您就可以查看它的項(然後滚動)。

    但始终避免在ScrollViews中使用GridViews.否則,您將需要計算每个child的身高,並將其重新分配為上面的蔡斯答案。

    <GridView
        android:id="@+id/gvFriends"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:verticalSpacing="5dp"
        android:horizontalSpacing="5dp"
        android:clipChildren="false"
        android:listSelector="@android:color/transparent"
        android:scrollbarAlwaysDrawHorizontalTrack="false"
        android:scrollbarAlwaysDrawVerticalTrack="false"
        android:stretchMode="columnWidth"
        android:scrollbars="none"
        android:numColumns="4"/>
    

  • .htaccess:Apache:服務器配置拒绝客戶端
  • gcc:如何在Linux中編譯靜態庫?