web-dev-qa-db-ja.com

GridViewを更新する方法は?

実行時に(サブアクティビティを介して)ImageViewを追加することを除けば、Googleチュートリアルとかなり似たGridViewがあります。結果は大丈夫ですが、ビューのレイアウトはめちゃくちゃになっています:GridViewは親のコンテンツを埋めていません。適切に設計するにはどうすればよいですか?

ここに子を追加するコード:

public void initializeWorkbench(GridView gv, Vector<String> items) {
        Prototype.workbench.setDimension(screenWidth, divider.height()+workbenchArea.height());
        Prototype.workbench.activateWorkbench();
        // this measures the workbench correctly
        Log.d(Prototype.TAG, "workbench width: "+Prototype.workbench.getMeasuredWidth());
        // 320
        Log.d(Prototype.TAG, "workbench height: "+Prototype.workbench.getMeasuredHeight());
        // 30
        ImageAdapter imgAdapter = new ImageAdapter(this.getContext(), items);
        gv.setAdapter(imgAdapter);
        gv.measure(screenWidth, screenHeight);
        gv.requestLayout();
        gv.forceLayout();
        Log.d(Prototype.TAG, "gv width: "+gv.getMeasuredWidth());
        // 22
        Log.d(Prototype.TAG, "gv height: "+gv.getMeasuredHeight());
        // 119
        Prototype.workbench.setDimension(screenWidth, divider.height()+workbenchArea.height());
    }
}

ワークベンチ内のactivateWorkbench、setDimensionおよびmeasure(GridViewの上のLinearLayout):

public void activateWorkbench() {
    if(this.equals(Prototype.workbench)) {
        this.setOrientation(VERTICAL);
        show = true;
        measure();
    }
}

public void setDimension(int w, int h) {
    width = w;
    height = h;
    this.setLayoutParams(new LinearLayout.LayoutParams(width, height));
    this.invalidate();
}

private void measure() {
    if (this.getOrientation() == LinearLayout.VERTICAL) {
        int h = 0;
        int w = 0;
        this.measureChildren(0, 0);
        for (int i = 0; i < this.getChildCount(); i++) {
            View v = this.getChildAt(i);
            h += v.getMeasuredHeight();
            w = (w < v.getMeasuredWidth()) ? v.getMeasuredWidth() : w;
        }
        if (this.equals(Prototype.tagarea))
            height = (h < height) ? height : h;
        if (this.equals(Prototype.tagarea))
            width = (w < width) ? width : w;
    }
    this.setMeasuredDimension(width, height);
}

ImageAdapterコンストラクター:

public ImageAdapter(Context c, Vector<String> items) {
    mContext = c;

    boolean mExternalStorageAvailable = false;
    boolean mExternalStorageWriteable = false;
    String state = Environment.getExternalStorageState();

    if (Environment.MEDIA_MOUNTED.equals(state)) {
        // We can read and write the media
        mExternalStorageAvailable = mExternalStorageWriteable = true;
    } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        // We can only read the media
        mExternalStorageAvailable = true;
        mExternalStorageWriteable = false;
    } else {
        // Something else is wrong. It may be one of many other states, but
        // all we need
        // to know is we can neither read nor write
        mExternalStorageAvailable = mExternalStorageWriteable = false;
    }

    if (mExternalStorageAvailable && mExternalStorageWriteable) {
        for (String item : items) {
            File f = new File(item);
            if (f.exists()) {
                try {
                    FileInputStream fis = new FileInputStream(f);
                    Bitmap b = BitmapFactory.decodeStream(fis);
                    bitmaps.add(b);
                    files.add(f);
                } catch (FileNotFoundException e) {
                    Log.e(Prototype.TAG, "", e);
                }
            }
        }
    }
}

そしてxmlレイアウト:

<LinearLayout   xmlns:Android="http://schemas.Android.com/apk/res/Android" 
            Android:layout_width="fill_parent" 
            Android:layout_height="fill_parent"
                Android:orientation="vertical"
                Android:gravity="bottom"

                Android:paddingLeft="0px"
                Android:paddingTop="0px"
                Android:paddingRight="0px">

    <com.unimelb.pt3.ui.TransparentPanel
            Android:id="@+id/workbench" 
            Android:layout_width="fill_parent"
            Android:layout_height="10px"
            Android:paddingTop="0px"
            Android:paddingLeft="0px"
            Android:paddingBottom="0px"
            Android:paddingRight="0px">

        <GridView xmlns:Android="http://schemas.Android.com/apk/res/Android" 
            Android:id="@+id/gridview"
            Android:layout_width="fill_parent" 
            Android:layout_height="fill_parent"
            Android:columnWidth="90dp"
            Android:numColumns="auto_fit"
            Android:verticalSpacing="10dp"
            Android:horizontalSpacing="10dp"
            Android:stretchMode="columnWidth"
            Android:gravity="center" />

    </com.unimelb.pt3.ui.TransparentPanel>

</LinearLayout>
30
Daniel

gridViewにはinvalidateViews()メソッドがあります。

このメソッドを呼び出すとき:「再構築および再描画されるすべてのビュー」。 http://developer.Android.com/reference/Android/widget/GridView.html

私はこれがあなたが必要なものだと思う:)

42
flyerz

最初に、データが変更されたことを通知するようアダプターに指示し、アダプターをグリッドに再度設定する必要があります

adapter.notifyDataChanged();
grid.setAdapter(adapter);
34
snagnever

これは役に立つかもしれません。アイテムで削除が実行された後、ブックイメージのサムネイルのグリッドビューを更新します。 adapter.notifyDataChanged();の使用上記のように、それは私のアダプターで呼び出されるので、私にとってはうまくいきませんでした。

//this is a call that retrieves cached data.
//your constructor can be designed and used without it.
final Object data = getLastNonConfigurationInstance();

基本的に、アダプターをリロードして同じビューにバインドします。

//reload the adapter
adapter = new BooksAdapter(MyBooks.this, MyBooks.this, data, show_collection );
grid.invalidateViews();
grid.setAdapter(adapter);
18
Rickey

ええええ

一緒にあなたはそれを持っています。そのはず:

adapter.notifyDataChanged();
grid.invalidateViews();

これにより、データが変更されたことをアダプターに通知し、invalidateViews()メソッドが呼び出された後はいつでもグリッドに伝達されます。

グリッドのレンダリング後にアイテムをグリッドに追加する方法がわからなかったため、この質問を見つけました。

10
Hobo

これらの答えのどれも実際に私にとってはうまくいかず、私はそれらすべてを一緒につぶさなければなりませんでした。 GridViewを実際に更新するには、これを行う必要があります。

 adapter.notifyDataChanged();
 grid.invalidateViews();
 grid.setAdapter(adapter);

これが、他のソリューションを機能させることができなかった人に役立つことを願っています。

9
edwoollard

invalidateViewsおよびsetAdapterを呼び出して、grid view。これは、grid viewが更新されました。そのように更新すると、多くの時間とメモリがかかります。

getViewメソッドを見る機会がある場合は、convertViewが一度だけ作成されることがわかります。 notifyDataChangedを呼び出すと、このビューが更新されます。一方、invalidateViewsを呼び出すと、以前に作成されたビューが再作成されます。これは良い解決策ではありません。

getViewを呼び出すと、notifyDataChangedメソッドが呼び出されます。したがって、getViewメソッドは次のコードのようになります。

public List list;

public class SimpleItemViewHolder extends Object
{
    public TextView textView;
    public ImageView imageView;
}

public View getView(int position, View convertView, ViewGroup parent){

    View itemView = convertView;
    SimpleItemViewHolder viewHolder;

    if(convertView==null)
    {
        viewHolder = (SimpleItemViewHolder)itemView.getTag();

    }else{
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        itemView = inflater.inflate(R.layout.layout_name, null);
        TextView labelField = (TextView) itemView.findViewById(R.id.label_field);
        labelField.setText(list.get(position).Name);
        //Typeface boldFont = Typeface.createFromAsset(context.getAssets(), "fonts/Font-Bold.ttf");
        //labelField.setTypeface(boldFont);

        ImageView imageView = (ImageView) itemView.findViewById(R.id.image_view);
        //Bitmap bitmap = init your bitmap here;
        //imageView.setImageBitmap(bitmap);  

        viewHolder = new SimpleItemViewHolder();
        viewHolder.imageView = imageView;
        viewHolder.textView = labelField;
        itemView.setTag(viewHolder);

    }

    //don't create new views, instead use previous ones and update them.
    viewHolder.textView.setText(list.get(position).Name);
    //viewHolder.imageView.setImageBitmap(your_bitmap);  
    return itemView;
}
5
aytek
adapter.notifyDataChanged();

アダプタのデータが古いために機能しない場合があります(アクティビティまたはフラグメントが破壊されず、たとえばバックスタックに座っていた場合)。

そのため、最初にデータを更新する場合、その後は動作します。

2
Andrey

アダプターで:

class MAdapter extends BaseAdapter{
   List<Objects> mObjects;
...

 public void clearAdapter(){
        mObjects.clear();
    }

 public void addNewValues(List<Objects> mObjects){
        this.mObjects = mObjects;
    }

...

}


adapter.clearAdapter(); // clear old values
adapter.addNewValues(MObjects);
adapter.notifyDataChanged();
0
Gilberto Ibarra

com.unimelb.pt3.ui.TransparentPanel高さの10pxの中にGridViewを配置しています。

  • pxは使用しないでください。dpを使用してください。
  • com.unimelb.pt3.ui.TransparentPanelAndroid:layout_height="10px"Android:layout_height="fill_parent"に変更します
0
Macarse