実行時に(サブアクティビティを介して)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>
gridViewにはinvalidateViews()メソッドがあります。
このメソッドを呼び出すとき:「再構築および再描画されるすべてのビュー」。 http://developer.Android.com/reference/Android/widget/GridView.html
私はこれがあなたが必要なものだと思う:)
最初に、データが変更されたことを通知するようアダプターに指示し、アダプターをグリッドに再度設定する必要があります
adapter.notifyDataChanged();
grid.setAdapter(adapter);
これは役に立つかもしれません。アイテムで削除が実行された後、ブックイメージのサムネイルのグリッドビューを更新します。 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);
ええええ
一緒にあなたはそれを持っています。そのはず:
adapter.notifyDataChanged();
grid.invalidateViews();
これにより、データが変更されたことをアダプターに通知し、invalidateViews()メソッドが呼び出された後はいつでもグリッドに伝達されます。
グリッドのレンダリング後にアイテムをグリッドに追加する方法がわからなかったため、この質問を見つけました。
これらの答えのどれも実際に私にとってはうまくいかず、私はそれらすべてを一緒につぶさなければなりませんでした。 GridViewを実際に更新するには、これを行う必要があります。
adapter.notifyDataChanged();
grid.invalidateViews();
grid.setAdapter(adapter);
これが、他のソリューションを機能させることができなかった人に役立つことを願っています。
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;
}
adapter.notifyDataChanged();
アダプタのデータが古いために機能しない場合があります(アクティビティまたはフラグメントが破壊されず、たとえばバックスタックに座っていた場合)。
そのため、最初にデータを更新する場合、その後は動作します。
アダプターで:
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();
com.unimelb.pt3.ui.TransparentPanel
高さの10px
の中にGridView
を配置しています。
px
は使用しないでください。dp
を使用してください。com.unimelb.pt3.ui.TransparentPanel
のAndroid:layout_height="10px"
をAndroid:layout_height="fill_parent"
に変更します