15

Android に GridView があり、xml リソースから取得したデータを入力します。
たとえば、GridView に 15 個のアイテムが順番に配置されています。全体の高さが画面の高さを超えているため、スクロールして残りの項目を表示する必要があります。
問題は、上にスクロールすると、非表示の行の順序が変更されたことです。アイテムが互いに行を入れ替えることがあるため、これは不思議な動作です。これが私のgetView方法です:

public class ImageAdapter extends BaseAdapter {
        public ImageAdapter(Context c, NodeList cuu) {
                cu = cuu;
        }
        public int getCount() {
                Log.d("Node Count",cu.getLength()+"");
                return cu.getLength();
        }
        public Object getItem(int position) {
                return position;
        }
        public long getItemId(int position) {
                return position;
        }
        public View getView(int position, View convertView, ViewGroup parent) {
                View myView = convertView;
                if (convertView == null) {
                    Node nd = cu.item(position);
                    Log.d("nodes","Pos: "+(position)+" Name: "+nd.getNodeName()+" Title: "+nd.getAttributes().getNamedItem("title").getTextContent());
                    int catID = Integer.parseInt(nd.getAttributes().getNamedItem("id").getTextContent());
                    LayoutInflater li = getLayoutInflater();
                    myView = li.inflate(R.layout.grid_item, null);
                   ImageView imageView = (ImageView) myView.findViewById(R.id.grid_item_image);
                   myView.setLayoutParams(new GridView.LayoutParams(70, 100));
                   id.download(nd.getAttributes().getNamedItem("icon").getTextContent(),imageView);
                   TextView textView = (TextView) myView.findViewById(R.id.grid_item_text);
                   textView.setText(nd.getAttributes().getNamedItem("title").getTextContent());
                   myView.setTag((Object) catID);
                }else{
                    //Log.d("nodes","Pos: "+(position));
                }
                return myView;
        }
        private NodeList cu = null;
    }

更新:まあ、それはかなり奇妙です。さらにデバッグを行った後、GridView でアダプターが 13 番目の位置をスキップしていることに気付きました。つまり、13 ではなく 1 を返し、14 に移動します!!! (13は不運だと思います!)

4

6 に答える 6

11
public View getView(int position, View convertView, ViewGroup parent) {
    View view;
    if (convertView == null) {
        view= inflate your xml
    } else {
        view=convertView;
    }
    // all remaining code like 
    // view.findViewById(R.id.btn).setText("MyButton");                            
    // must be outside if-else
}
于 2013-07-08T09:48:25.190 に答える
8

それがメソッドにあるすべてのコードである場合、getView正しく実装していません。

public View getView(int position, View convertView, ViewGroup parent) {
        View myView = convertView;
        if (myView == null) {           
            Node nd = cu.item(position);
            int catID = Integer.parseInt(nd.getAttributes().getNamedItem("id")
                    .getTextContent());
            LayoutInflater li = getLayoutInflater();
            myView = li.inflate(R.layout.grid_item, null);
            myView.setLayoutParams(new GridView.LayoutParams(70, 100));         
            myView.setTag((Object) catID);
        } 
        Node nd = cu.item(position);
        Log.d("nodes", "Pos: " + (position) + " Name: " + nd.getNodeName()
                + " Title: "
                + nd.getAttributes().getNamedItem("title").getTextContent());
        ImageView imageView = (ImageView) myView
                .findViewById(R.id.grid_item_image);
        id.download(nd.getAttributes().getNamedItem("icon")
                .getTextContent(), imageView);
        TextView textView = (TextView) myView
                .findViewById(R.id.grid_item_text);
        textView.setText(nd.getAttributes().getNamedItem("title")
                .getTextContent());
        return myView;
    }

上記のコードが機能するかどうかはわかりませんが、あなたのコードは少し奇妙です。とにかく、アダプターで行うのは最初に表示される要素を入力することだけであり、リサイクルのために上下にスクロールすると、アダプターはまったく同じ要素を再利用するため、通常の動作だと思います。では、次のgetViewことを行う必要があります。

  • かどうかを確認しconvertViewますnull
    • その場合は、 thisの要素のnullnew を膨らませます。ホルダー パターンを使用して、(毎回検索する代わりに)構成を探してキャッシュすることもできます(膨張したビューに要素を使用しますが、それはデータ要素からのデータの一部です?!? それをどうする予定ですか? ?!?)ViewGridViewViewsfindViewByIdsetTagNode
    • そうでないnull場合は何もしません(またはホルダーパターンを実装すると、既に検索されたタグが取得されますViews

そして、これはその if/else ステートメントで行うべきことです

  • 上記の部分の後、Viewsデータを入力します(その位置に適切なデータを保持します)。
于 2012-05-20T11:49:22.430 に答える
3

アダプターの実装に致命的な欠陥があります。

ではgetView()convertViewnullの場合、レイアウトを膨張させ、そのウィジェットにデータを入力します。これで問題ありません。

では、そうでないgetView()場合は、まったく何もしません。これは非常に間違っています。convertViewnull

で行うべきことはgetView()、そうconvertViewでないnull場合でも、セルのウィジェットにデータを入力することです。リサイクルされるセルを表すため、インフレをスキップして CPU 時間を節約できますが、この特定の呼び出しconvertViewで設定する予定の位置を反映するようにそのセルのウィジェットを更新する必要があります。getView()

于 2012-05-20T11:43:01.773 に答える
1

Grid アイテムに複数のビューがあるgetTag()場合は、 メソッドとメソッドを使用できますsetTag()。この場合、グリッド アイテムはスクロールしても位置が変わらず、パフォーマンスは問題ありません。

public class SomeAdapter extends BaseAdapter {

    public static class ViewHolder {
        public TextView tvTitle;
        public ImageView imgPoster;
    }

    //...
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder grid;
        LayoutInflater inflator = activity.getLayoutInflater();

        if (convertView == null) {
            grid = new ViewHolder();
            convertView = inflator.inflate(R.layout.grid_item, null);
            grid.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
            grid.imgPoster = (ImageView) convertView.findViewById(R.id.img_poster);

            convertView.setTag(grid);   // <<-- H E R E
        } else {
            grid = (ViewHolder) convertView.getTag();   // <<-- H E R E
        }
        grid.tvTitle.setText(dataItem.getTitle());
        grid.imgPoster.setImage(dataItem.getImage());
        return convertView;
    }
}
于 2016-09-29T00:34:57.233 に答える
0

別のサンプルに基づいてこのソリューションを使用し、作業しました:

public View getView(int position, View convertView, ViewGroup parent) {
    View view = null;
    if (convertView == null) {
        view = inflate your xml and apply the View Holder pattern
    } else {
        view = convertView;
    }
    // retrieve the object by Holder pattern 
    // extra code here
}
于 2014-06-02T20:09:17.250 に答える