这是我的问题的ListView截图:
这是布局XML:
<LinearLayout
android:id="@+id/viewer_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/background_dark"
android:orientation="vertical" >
<EditText
android:id="@+id/viewer_filter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableRight="@android:drawable/ic_menu_search"
android:hint="@string/hint_filter"
android:background="@android:color/white"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="3dp"
android:inputType="text"
android:paddingLeft="4dp"
android:selectAllOnFocus="true" >
</EditText>
<EditText
android:id="@+id/viewer_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableRight="@android:drawable/ic_menu_search"
android:hint="@string/hint_search"
android:background="@android:color/white"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="3dp"
android:layout_marginBottom="5dp"
android:inputType="text"
android:paddingLeft="4dp"
android:selectAllOnFocus="true" >
</EditText>
</LinearLayout>
<HorizontalScrollView
android:id="@+id/viewer_hscroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/viewer_top" >
<ListView
android:id="@+id/viewer_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
</HorizontalScrollView>
此方案中存在3个问题:
ListView行的宽度不均匀(这可以通过背景颜色结尾看到)(有关详细信息,请参阅下面的getView代码)
private static final int listRowLayout = android.R.layout.activity_list_item;
private Map<String, Integer> mColors = new HashMap<String, Integer>();
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// No logs here to keep ListView performance good
ViewHolder holder;
int color;
if( convertView == null ) {
convertView = mInflater.inflate(listRowLayout, parent, false);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(android.R.id.text1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String data = mData.get(position);
// A compiled regex is faster than String.Contains()
Matcher m = ViewHolder.regex.matcher(data);
if( m.find() ) {
color = mColors.get(m.group(1));
} else {
color = mColors.get("V");
}
holder.text.setText(data);
holder.text.setBackgroundColor(color);
return convertView;
}
private static class ViewHolder {
TextView text;
static Pattern regex = Pattern.compile(" ([VIDWEF])/");
}
}
答案 0 :(得分:1)
我在尝试显示日志文件时遇到了完全相同的问题。我有一个专门的活动来显示日志文件:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_log);
// Read in lines from the log file
File clientLogFile = new File(LOG_FILE);
ArrayList<String> lines = new ArrayList<String>();
try
{
Scanner scanner = new Scanner((Readable) new BufferedReader(new FileReader(clientLogFile)));
try
{
while(scanner.hasNextLine())
{
lines.add(scanner.nextLine());
}
}
finally
{
scanner.close();
}
}
catch (FileNotFoundException e)
{
lines.add("No log file");
}
// Create a simple adaptor that wraps the lines for the ListView
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item,lines);
// Create a ListView dynamically to overide onMeasure()
final ListView listView = new ListView(this)
{
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// Override onMeasure so we can set the width of the view to the widest line in the log file
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Find maximum width of item in list and set scroll width equal to that
int maxWidth = 0;
for(int i=0; i<getAdapter().getCount(); i++)
{
View listItem = getAdapter().getView(i, null, this);
listItem.measure(0, 0);
int width = listItem.getMeasuredWidth();
if(width > maxWidth)
{
maxWidth = width;
}
}
// Set width of measured dimension
setMeasuredDimension(maxWidth, getMeasuredHeight());
}
};
// Add to scroll view
HorizontalScrollView horizontalScrollView = (HorizontalScrollView)findViewById(R.id.logScrollView);
horizontalScrollView.addView(listView);
// Set adaptor
listView.setAdapter(adapter);
// Enable fast scroll
listView.setFastScrollEnabled(true);
// Scroll to end
listView.post(new Runnable(){
public void run() {
listView.setSelection(listView.getCount() - 1);
}});
}
onCreate方法读取日志文件,然后动态地将ListView添加到HorizontalScrollView并重写onMeasure()。 onMeasure()代码确定适配器中视图的最大宽度,并将ListView宽度设置为。
因此,我的activity_view_log.xml布局文件非常简单:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp"
>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/logScrollView">
</HorizontalScrollView>
</RelativeLayout>
为了对ListView中的行进行更精细的控制,我在list_item.xml中为我的适配器提供了我自己的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:inputType="text|none"
/>
在onCreate()的最后,我启用快速滚动,并滚动到日志文件中行的末尾。
答案 1 :(得分:0)
我可能会改变你正在做的事情。创建一个ListView并使listview中的每个项目都可以水平滚动。这样项目只在需要时滚动,并且不会滚动整个屏幕。并且您可以完全控制每个列表项的维度。为此,请使用注释中提到的自定义列表视图适配器。您的问题也可能与此处重复:Android horizontal scroll list
答案 2 :(得分:0)
为了解决3个问题,我必须使所有组件(水平滚动视图,列表视图及其项目)具有“fill_parent”宽度(我认为它与“match_parent”相同)。另外,我重写了listview的onMeasure(...)
以计算其项目的最大宽度,并通过setMeasuredDimension(...)
进行设置。这将通过它最宽泛的项目来衡量视图,而不是它现在实现的第一个。
答案 3 :(得分:0)
这是我找到的解决方案
所有邪恶的根源:-)是ListView不是为有效地处理不同长度的行而设计的。要确定ListView宽度,而不是查看所有行,只有3行被视为 average 。
因此,如果3行是偶然的短行,对于较长的行,宽度将剪裁,它解释了我遇到的问题。
为了绕过这个,我计算了所有数据的最大行长度,并用空格填充了较短的行,它解决了我在问题中描述的所有3个问题。
填充代码(在getView()
内执行)
holder.text.setText(String.format("%1$-" + mLen + "s", data));