自定义适配器视图(带图片)

时间:2013-07-26 21:37:36

标签: java android xml android-layout layout

我正在尝试创建一个如下所示的布局:

the look that i'm trying to achieve
输入EditText并在AdapterView中动态解析并显示为自己的TextView的单词。如果EditText中没有输入任何内容,则AdapterView也将为空。如果一行中有太多单词,则将它们添加到下一行。最后,你会得到一个填充适配器的TextViews“砖墙”。

我很想找到关于如何实现这种外观的任何指南。我想尽可能多地定义XML中的内容。我想象的是这样的:

<!-- Activity.xml -->
<RelativeLayout>
     <TextView>
     <EditText>
     <AdapterView>
</RelativeLayout>

但是现有的适配器(ListView,GridView)都不适合我在这里尝试做的事情。

有人能给我一些学习的例子吗?

3 个答案:

答案 0 :(得分:1)

如果您尝试创建具有自定义外观的列表,那么您是正确的,基本列表视图适配器是不合适的。你需要创建自己的。

您可以通过创建一个扩展ArrayAdapter的类和一个使用上面定义预定义的xml视图来完成此操作:

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ExampleAdapter extends ArrayAdapter<Object> {

    private int resource;
    private LinearLayout layoutItem;

    public ExampleAdapter(Context context, int _resource, ArrayList<Object> itemList) {     
        super(context, _resource, itemList);        
    }

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

        try{

            //****************************************************
            // instantiate the layout
            //****************************************************
            if(convertView == null){
                layoutItem = new LinearLayout(getContext());
                String inflater = Context.LAYOUT_INFLATER_SERVICE;
                LayoutInflater vi;
                vi = (LayoutInflater)getContext().getSystemService(inflater);
                vi.inflate(resource, layoutItem, true);         
            }else{
                layoutItem = (LinearLayout) convertView;
            }


            //****************************************************
            // bind the layout controls
            //****************************************************
            TextView myTextView = (TextView)layoutItem.findViewById(R.id.myTextView);
            // extend to other view controls...

            //****************************************************
            // use the item object to get information about it
            //****************************************************          
            int Id = item.get_id();


            // do whatever else you need to the display of the layout




            return layoutItem;

        }catch(Exception e){
             e.printStackTrace();
        }       

}

现在,您可以调用自定义适配器来传递需要与布局资源一起显示的项目列表,而不是调用基本适配器。

答案 1 :(得分:0)

在您的情况下,GridView是最好的解决方案,因为如果空间不足,它可以自动换行到下一行。

您不直接使用AdapterView,使用其中一个子类(如GridView)和一个将getView中的TextViews返回到每个单词的BaseAdapter。

答案 2 :(得分:0)

谢谢你们的答案,但我决定回答我自己的问题,因为我觉得有一些额外的细节很重要。

不幸的是,所有这些仍然不会产生我在原始问题中描述的外观。为此,我们将需要一个自定义布局(我现在正在处理),但是如果没有这样做,这就像我们将要获得的那样接近。

此示例将向您展示如何使用自定义元素填充GridView(AdapterView类型)(在本例中为Text + Icon)

主要活动的xml

<!-- Item.xml -->
<RelativeLayout>
   <TextView>
   <EditText>
   <GridView>
</RelativeLayout>

将添加到适配器的项目的xml文件。

<!-- Item.xml -->
<RelativeLayout>
   <TextView>
   <ImageView>
</RelativeLayout>

自定义布局类,在实现之前观察此(仅前10分钟左右):http://www.youtube.com/watch?v=N6YdwzAvwOA

public class MyAdapter extends ArrayAdapter<Object> {

    //members
    public static class ViewHolder {
        TextView tv;
        ImageView iv;
    }
    private LayoutInflater m_Inflater;
    private ArrayList<Object> m_UnderlyingData;

    // context - context
    // _resource - view defined in xml (will be added to adapter view)
    // itemList - data to fit into view from resource
    public MyAdapter(final Context _context, final int _resource, final ArrayList<Object> _itemList) {    
        super(_context, _resource, _itemList);

        m_Inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        m_UnderlyingData = _itemList;
    }

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

        ViewHolder oHolder;

        if(convertView == null){
            convertView = m_Inflater.inflate(R.layout.word_item, null);

            // -- remember views that make up the item layout
            oHolder = new ViewHolder();
            oHolder.tv = (TextView) convertView.findViewById(R.id.tv_word);
            oHolder.iv = (ImageView) convertView.findViewById(R.id.iv_icon);

            // -- reference to views that can be accessed outside of this class
            convertView.setTag(oHolder);
        }else{
            oHolder = (ViewHolder) convertView.getTag();
        }

        //set new data
        oHolder.tv.setText((String) m_UnderlyingData.get(position));
        oHolder.iv.setImageResource(R.drawable.icon);

        return convertView;
    }
}

这是在活动中使用的代码:

GridView oWordGrid = (GridView) findViewById(R.id.myGrid);
ArrayList<Object> oArrayList = new ArrayList<Object>();
oArrayList.add("abc");
oArrayList.add("def");
oArrayList.add("blah");
ListAdapter myAdapter = new MyAdapter(this, R.layout.word_item, oArrayList);
oWordGrid.setAdapter(myAdapter);

PS

这是一些更具教育性的材料:
http://www.youtube.com/watch?v=wDBM6wVEO70
http://www.youtube.com/watch?v=NYtB6mlu7vA