Java 通过扩展ArrayAdapter在ListView中显示和排列LinearLayout对象
我有一个线性布局列表。每个LinearLayout都包含通过编程添加的几个其他视图 我想做的是在ListView中显示这些LinearLayout视图,以便利用ListView的功能仅渲染所需的内容 我的原始代码使用了在布局xml中定义的ScrollView,我通过编程将我的每个LinearLayout添加到ScrollView中,效果很好 现在,我用ListView替换了xml中的ScrollView,并添加了一个适配器 在下面的例子中,我简化了一切,试图找到问题的根源。当适配器的getView方法返回LinearLayout时,我得到一个ClassCastException 活动布局xml(trend_scrollable.xml):Java 通过扩展ArrayAdapter在ListView中显示和排列LinearLayout对象,java,android,listview,adapter,Java,Android,Listview,Adapter,我有一个线性布局列表。每个LinearLayout都包含通过编程添加的几个其他视图 我想做的是在ListView中显示这些LinearLayout视图,以便利用ListView的功能仅渲染所需的内容 我的原始代码使用了在布局xml中定义的ScrollView,我通过编程将我的每个LinearLayout添加到ScrollView中,效果很好 现在,我用ListView替换了xml中的ScrollView,并添加了一个适配器 在下面的例子中,我简化了一切,试图找到问题的根源。当适配器的getVie
每行的布局(simple\u chart\u item.xml):
适配器:
public class ChartArrayAdapter extends ArrayAdapter<LinearLayout>
{
ArrayList<LinearLayout> layoutList;
public ChartArrayAdapter(Context context, ArrayList<LinearLayout> list)
{
super(context, R.layout.simple_chart_item, list);
this.layoutList = new ArrayList<LinearLayout>(list);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
return layoutList.get(position);
}
@Override
public int getCount()
{
return this.layoutList != null ? this.layoutList.size() : 0;
}
}
public class ChartArrayAdapter extends ArrayAdapter<LinearLayout>
{
public ChartArrayAdapter(Context context, ArrayList<LinearLayout> list)
{
super(context, R.layout.simple_chart_item, list);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
return this.getItem(position);
}
}
公共类ChartArrayAdapter扩展了ArrayAdapter
{
ArrayList布局列表;
公共ChartArrayAdapter(上下文,ArrayList列表)
{
超级(上下文、右布局、简单图表、项目、列表);
this.layoutList=新的ArrayList(列表);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图)
{
返回布局列表。获取(位置);
}
@凌驾
public int getCount()
{
返回this.layoutList!=null?this.layoutList.size():0;
}
}
活动:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.trend_scrollable);
ListView layout = (ListView) findViewById(R.id.trend_listview);
ArrayList<LinearLayout> layoutList = new ArrayList<LinearLayout>();
for (int i = 0; i < 2; i++)
{
layoutList.add(getDemoView(GlobalVars.getContext(), i));
}
ChartArrayAdapter adapter = new ChartArrayAdapter(this, layoutList);
layout.setAdapter(adapter);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.trend_scrollable);
ListView layout = (ListView) findViewById(R.id.trend_listview);
ArrayList<LinearLayout> layoutList = new ArrayList<LinearLayout>();
for (int i = 0; i < 2; i++)
{
layoutList.add(getDemoView(this, i));
}
ChartArrayAdapter adapter = new ChartArrayAdapter(this, layoutList);
layout.setAdapter(adapter);
}
@覆盖
创建时受保护的void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
此.setContentView(R.layout.trend\u可滚动);
ListView布局=(ListView)findViewById(R.id.trend\u ListView);
ArrayList layoutList=新建ArrayList();
对于(int i=0;i<2;i++)
{
添加(getDemoView(GlobalVars.getContext(),i));
}
ChartArrayAdapter=新的ChartArrayAdapter(此,布局列表);
布局。设置适配器(适配器);
}
有人能帮我吗?我简化了适配器的getView方法,使其始终只返回LinearLayout视图,我认为这意味着将始终创建一个新视图。我怀疑返回的LinearView并将其与“simple_chart_layout.xml”相匹配可能有问题,可能..ListView的目的有两个:按需创建视图和循环使用视图。按需创建避免了在一次只显示一部分视图时必须先创建所有视图。视图循环使用避免了在用户滚动列表时必须将所有这些视图保留在内存中 现在,您正在
onCreate
中创建一大堆视图,并将它们存储在适配器中,这完全违背了上述两个目的。这实际上并不比您以前使用ScrollView所做的更好
您通常要做的是向适配器提供一些数据(比如字符串列表),它会按需将这些数据逻辑绑定到视图。在getView()
中,您将创建行布局(通过膨胀一个全新的行布局或重新使用提供的convertView
参数),用数据填充它,然后返回它。看起来像这样:
LayoutInflater inflater; // initialize in adapter's constructor
@Override
public View getView(int position, View convertView, ViewGroup container) {
if (convertView == null) {
// inflate if not recycled
convertView = inflater.inflate(R.layout.your_list_item, container, false);
}
// populate the views
TextView sampleText = (TextView) convertView.findViewById(R.id...);
sampleText.setText(...); // based on position argument and what data your adapter holds
return convertView;
}
这是基本版本;通常,您还可以使用,通过消除对findViewById
调用的需要来提高性能
我总是建议人们观看。您似乎已经对Android有了一些经验,但您可能会发现它很有帮助。在正确查看调试消息后,我的示例开始工作。我所做的是使用以下代码创建演示LinearView:
private static LinearLayout getDemoView(Context context, int i)
{
LinearLayout containerView = new LinearLayout(context);
LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
containerView.setLayoutParams(containerParams);
containerView.setOrientation(LinearLayout.HORIZONTAL);
TextView titleLabelView = new TextView(context, null);
titleLabelView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
titleLabelView.setText("Demo text view 1 - " + Integer.toString(i));
containerView.addView(titleLabelView);
TextView bodyLabelView = new TextView(context, null);
bodyLabelView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
bodyLabelView.setText("Demo text view 2 - " + Integer.toString(i));
containerView.addView(bodyLabelView);
return containerView;
}
这段代码只是创建一个LinearView,并在其中放置两个文本视图,其中包含一些文本
我在LogCat中遇到的错误是:
java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
通过注释掉以下行,我的代码工作了:
LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
containerView.setLayoutParams(containerParams);
代码的其余部分是:
适配器:
public class ChartArrayAdapter extends ArrayAdapter<LinearLayout>
{
ArrayList<LinearLayout> layoutList;
public ChartArrayAdapter(Context context, ArrayList<LinearLayout> list)
{
super(context, R.layout.simple_chart_item, list);
this.layoutList = new ArrayList<LinearLayout>(list);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
return layoutList.get(position);
}
@Override
public int getCount()
{
return this.layoutList != null ? this.layoutList.size() : 0;
}
}
public class ChartArrayAdapter extends ArrayAdapter<LinearLayout>
{
public ChartArrayAdapter(Context context, ArrayList<LinearLayout> list)
{
super(context, R.layout.simple_chart_item, list);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
return this.getItem(position);
}
}
公共类ChartArrayAdapter扩展了ArrayAdapter
{
公共ChartArrayAdapter(上下文,ArrayList列表)
{
超级(上下文、右布局、简单图表、项目、列表);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图)
{
返回此.getItem(位置);
}
}
活动:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.trend_scrollable);
ListView layout = (ListView) findViewById(R.id.trend_listview);
ArrayList<LinearLayout> layoutList = new ArrayList<LinearLayout>();
for (int i = 0; i < 2; i++)
{
layoutList.add(getDemoView(GlobalVars.getContext(), i));
}
ChartArrayAdapter adapter = new ChartArrayAdapter(this, layoutList);
layout.setAdapter(adapter);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.trend_scrollable);
ListView layout = (ListView) findViewById(R.id.trend_listview);
ArrayList<LinearLayout> layoutList = new ArrayList<LinearLayout>();
for (int i = 0; i < 2; i++)
{
layoutList.add(getDemoView(this, i));
}
ChartArrayAdapter adapter = new ChartArrayAdapter(this, layoutList);
layout.setAdapter(adapter);
}
@覆盖
创建时受保护的void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
此.setContentView(R.layout.trend\u可滚动);
ListView布局=(ListView)findViewById(R.id.trend\u ListView);
ArrayList layoutList=新建ArrayList();
对于(int i=0;i<2;i++)
{
添加(getDemoView(this,i));
}
ChartArrayAdapter=新的ChartArrayAdapter(此,布局列表);
布局。设置适配器(适配器);
}
问题是我将LinearLayout参数添加到一个要进入ListView的视图中。这是除了我之外没有人会知道的,因为我没有把这部分代码放在我最初的问题中——我的道歉
我在这里给出的是ListView的一个非常糟糕的实现,因为这是从ScrollView(其中我已经创建了所有LinearView)到ListView(其中视图由适配器动态创建)的中间步骤。此练习对我很有用,但对其他人可能没有用处,尽管它确实证明了您可以将任何内容的arraylist传递给自定义适配器,然后在从getView返回时创建任何您喜欢的视图。此线程中的答案有一个自定义listview的完整示例:谢谢您的回答。你说过我的实现离理想很远,这是正确的。youtube上谷歌教程的链接填补了我理解上的一些空白。我的想法是基于采取迭代步骤,从构建滚动视图的所有视图到正确的i