【问题标题】:Binding Cursor data to a non-list layout将光标数据绑定到非列表布局
【发布时间】:2022-01-29 01:21:22
【问题描述】:

我正在编写一个屏幕,显示来自数据库的一行信息。基本上,它是一个细节片段,表示与表格中的一个“行”有关的信息。我想了解将数据从游标(表格中的一个唯一行)绑定到文本视图、复选框等布局的最佳实践。

AdapterView 是票吗?

@JoeMalin 建议:

然后在光标和文本视图数组之间编写一个适配器。

这归结为我的问题。将一系列文本视图挂钩到光标的正确方法是什么?

【问题讨论】:

    标签: android android-cursor


    【解决方案1】:

    如果您想在将光标数据移动到文本视图之前对其进行处理,那么您将超越适配器模式,该模式假定将数据结构的形式“重铸”为另一个数据结构无需任何中间处理。适配器的优点在于,对于通过适配器链接的两个数据结构 A 和 B,假设 A 发生变化时 B 会自动发生变化。

    当然,您可以重新定义适配器的想法以插入您自己的中间操作,例如转换日期,您可以将转换作为显示数据的视图的一个方面。我猜“处理”实际上是格式化,你这样做是为了显示目的。这是文本视图的属性,而不是数据;编写一些扩展文本视图并根据需要转换日期的东西。然后在光标和文本视图数组之间编写一个适配器。

    【讨论】:

    • 你是对的,它是格式化,而不是处理。对于我的 ListViews,我在 bindView 中进行格式化。我看到我还可以将 TextView 扩展为知道如何在内部格式化日期时间的“TimeView”。我的问题仍然归结为您的最后一个建议:在光标和一组文本视图之间编写一个适配器。我不知道该怎么做,希望得到任何建议。
    【解决方案2】:

    我最近实现了自己的数据适配器类,它可能在球场上。

    public class NoteImageDataAdapter {
    
    private final View mMainView;
    private Cursor mCursor;
    private ViewHolder holder;
    private ContentObserver mContentObserver;
    
    public static class ViewHolder {
        public TextView title;
        public TextView text;
        public ImageView image;
    }
    
    public NoteImageDataAdapter(View mainView, Cursor c) {
        if (mainView == null) {
            throw new IllegalArgumentException("View mainView cannot be null");
        }
    
        if (c == null) {
            throw new IllegalArgumentException("Cursor c cannot be null");
        }
        mMainView = mainView;
        mCursor = c;
    
        holder = new ViewHolder();
        holder.title = (TextView) mMainView.findViewById(R.id.title);
        holder.text = (TextView) mMainView.findViewById(R.id.text);
        holder.image = (ImageView) mMainView.findViewById(R.id.myImageView);
    
        mContentObserver = new ImageNoteContentObserver(new Handler());
        mCursor.registerContentObserver(mContentObserver);
        bindView();
    }
    
    class ImageNoteContentObserver extends ContentObserver {
    
        public ImageNoteContentObserver(Handler handler) {
            super(handler);
        }
    
        @Override
        public boolean deliverSelfNotifications() {
            return true;
        }
    
        @Override
        public void onChange(boolean selfChange) {
            Log.d("NoteImageDataAdapter", "ImageNoteContentObserver.onChange( "
                    + selfChange + ")");
            super.onChange(selfChange);
            mCursor.requery();
            bindView();
        }
    }
    
    public void bindView() {
        Log.d("NoteImageDataAdapter", "bindView");
        mCursor.moveToFirst();
    
        holder.text.setText(Note.getText(mCursor));
        holder.title.setText(Note.getTitle(mCursor));
    
        Uri imageUri = Note.getImageUri(mCursor);
        if (imageUri != null) {
            assignImage(holder.image, imageUri);
        } else {
            Drawable d = Note.getImageThumbnail(mCursor);
            holder.image.setImageDrawable(d);
            holder.image.setVisibility(View.VISIBLE);
        }
    }
    
    private static final int MAX_IMAGE_PIXELS = 1024*512;
    
    private void assignImage(ImageView imageView, Uri imageUri){
        if (imageView != null && imageUri != null){
    
            ContentResolver cr = imageView.getContext().getContentResolver();
    
            Display display = ((WindowManager) imageView.getContext()
                    .getSystemService(Context.WINDOW_SERVICE))
                    .getDefaultDisplay();
            int width = (int) (display.getWidth() * 0.9);
            int height = (int) (display.getHeight() * 0.9);
    
            int minSideLength = Math.min(height, width);
    
            Bitmap b = Util.makeBitmap(minSideLength, MAX_IMAGE_PIXELS, imageUri, cr, false);
    
            if (b == null){
                b = Util.makeBitmap(minSideLength, MAX_IMAGE_PIXELS/2, imageUri, cr, false);                
            }
            if (b != null){
                imageView.setImageBitmap(b);
                imageView.setAdjustViewBounds(true);
                imageView.setVisibility(View.VISIBLE);
            }   
        }   
    }
    

    }

    在你的活动中

    private NoteImageDataAdapter mAdapter;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        setContentView(R.layout.note_image_view_layout);
    
        wireDataAdapter();       
    }
    
    private void wireDataAdapter() {
        final String[] COLUMNS = new String[] { 
                Note.Columns.TITLE,
                Note.Columns.TEXT,
                Note.Columns.IMAGE_URI, 
                Note.Columns.IMAGE_THUMBNAIL,
                Note.Columns._ID };
    
        // the uri for the note row
        Uri contentUri = getIntent().getData();
        Cursor cur = managedQuery(contentUri, COLUMNS, null, null, null);
    
        View mainLayout = this.findViewById(R.id.noteImageViewLayout);
        mAdapter = new NoteImageDataAdapter(mainLayout, cur);
    }
    

    【讨论】:

      【解决方案3】:

      来自活动使用:

      Adpater adapter = new Adapter(Activity.this or context , Cursor);
      setListAdapter(adapter) in case of List Activity;
      

      否则

      listViewObj.setAdpater(adapter)   
      

      公共类 CustomCursorAdapter 扩展 CursorAdapter {

       private LayoutInflater mInflater;
       private Context activityContext;
      
       private ViewHolder holder;
      
       public ContactsAdapter(Context aContext,Cursor cursor) {
              super(mContext, cursor);
              mInflater = LayoutInflater.from(mContext); 
              activityContext = aContext;
      
          }  
      
       public static class ViewHolder{
           public TextView textView1;
           // View Group on Row inflate lyaout that need to be used
           public ImageView imageView;
         }
      
       @Override
       public void bindView(View v, Context context, Cursor c) { 
        holder=(ViewHolder)v.getTag();
      
       }
      
      
       @Override
       public View newView(Context context, Cursor cursor, ViewGroup parent) {
        final LayoutInflater inflater = LayoutInflater.from(context);
              View v = inflater.inflate(R.layout.item_inflate_layout, parent, false);  
      
              holder = new ViewHolder();
           holder.textView1 = (TextView) v.findViewById(R.id.TEXTVIEW1);
        // Other Id that need to be used and are available on item_inflate_layout
           holder.imageView = (ImageView) v.findViewById(R.id.IMAGEVIEW);
           v.setTag(holder);     
        bindView(v, context, cursor);
              return v;  
       }
       }
      

      【讨论】:

      • 如何将适配器与其父级关联?即:setListAdapter?
      • 如果你现在使用 ListActivity 那么 Adpater adpater = new Adpater(context,Cursor); listView.setAdpater(adpater)
      • 我的问题是针对非列表活动。我没有显示列表,而是显示列表中一项的详细信息。
      • 所需的布局是一组文本视图,每个视图对应于表格中一行的列数据。某些数据(如日期)需要在设置到 textview 之前进行处理。
      • 这没有回答原始问题。有许多示例使用适配器将包含多行的游标绑定到列表视图。实际问题是如何使用适配器将包含单个项目的游标绑定到单个视图。 setAdapter 方法只存在于扩展/实现AdapterView 的视图中。例如,使用光标、适配器和项目主列表的列表视图启动活动。然后从该列表中选择一个项目以启动一个单独的活动,其中包含该单个项目详细信息的光标、适配器和线性布局。您如何绑定该单项活动?
      猜你喜欢
      • 2011-10-17
      • 1970-01-01
      • 2016-01-02
      • 2013-02-15
      • 1970-01-01
      • 2015-10-31
      • 2016-08-31
      • 1970-01-01
      • 2012-09-06
      相关资源
      最近更新 更多