为什么 ListView.Header 中的这个标签不能显示所有文本?
Why can't this label in ListView.Header show all text?
Android: 6.0
Xamarin.Forms: 2.1.0.6529
创建一个新的 Xamarin.Forms 项目并粘贴:
class Model
{
public string Text
{
get;
set;
}
}
public class App : Application
{
public App()
{
var label = new Label
{
BackgroundColor = Color.Yellow,
Text = genLongText(),
HeightRequest = 10000, // force height
};
var list = new List<Model>();
for (int i = 0; i < 10; i++)
{
list.Add(new Model { Text = i + " list item" });
}
var template = new DataTemplate(typeof(TextCell));
template.SetBinding(TextCell.TextProperty, nameof(Model.Text));
var listview = new ListView
{
Header = label,
ItemsSource = list,
ItemTemplate = template,
BackgroundColor = Color.Blue,
};
var content = new ContentPage
{
Title = "test",
Content = listview
};
MainPage = new NavigationPage(content);
}
private string genLongText()
{
var t = " Welcome to Xamarin Forms!\n";
var s = "";
for (int i = 0; i < 2000; i++)
{
s += i.ToString() + t;
}
return s;
}
}
结果是这样的:
如您所见,文本被裁剪并且只显示前 100 行。标签本身(黄色背景)很好,因为我强制高度很大,否则标签的高度也会是同样的长度。
所以,基本上如果你在标签上设置一个很长的文本,它只会展开显示前 100 行,如果你通过 HeightRequest 手动改变它的高度,那么标签会很好,但文本仍然是剪掉了。
这必须与 ListView.Header 实施有关。
在 Android 上,表单的 ListView
是 android.widget.ListView
,其中 ListView 的 header 被设置为包含您的选择的 Container
的 VisualElement
。
由于您使用的表单 Label
是 Android TextView
,因此 100 行文本是在 Android 小部件 class.尝试通过 Forms 的 ListViewRenderer.cs Container OnMeasure 方法设置高度不会覆盖它。
来自ListViewRenderer.cs
int heightSpec = MeasureSpecFactory.MakeMeasureSpec((int)ctx.ToPixels(request.Request.Height), MeasureSpecMode.Exactly);
_child.ViewGroup.Measure(widthMeasureSpec, heightMeasureSpec);
如果您真的需要在 ListView 中显示那么多文本 Header 无需 创建自定义 ListViewRender 并手动操作该 Container 中 TextView 的 SetLines、SetMinLines 和 SetMaxLines,使用 Forms' Editor
(禁用)代替 header 的 VisualElement
:
var label = new Editor
{
BackgroundColor = Color.Yellow,
Text = genLongText(),
MinimumHeightRequest = 10000,
IsEnabled = false
};
您还可以将 header 已禁用 Editor
嵌入 ScrollView
并将其指定为 ListView
Header
,这样您就可以在其中滚动文本Editor
:
var scrollViewHeader = new ScrollView
{
HeightRequest = 200,
Content = label
};
Android: 6.0
Xamarin.Forms: 2.1.0.6529
创建一个新的 Xamarin.Forms 项目并粘贴:
class Model
{
public string Text
{
get;
set;
}
}
public class App : Application
{
public App()
{
var label = new Label
{
BackgroundColor = Color.Yellow,
Text = genLongText(),
HeightRequest = 10000, // force height
};
var list = new List<Model>();
for (int i = 0; i < 10; i++)
{
list.Add(new Model { Text = i + " list item" });
}
var template = new DataTemplate(typeof(TextCell));
template.SetBinding(TextCell.TextProperty, nameof(Model.Text));
var listview = new ListView
{
Header = label,
ItemsSource = list,
ItemTemplate = template,
BackgroundColor = Color.Blue,
};
var content = new ContentPage
{
Title = "test",
Content = listview
};
MainPage = new NavigationPage(content);
}
private string genLongText()
{
var t = " Welcome to Xamarin Forms!\n";
var s = "";
for (int i = 0; i < 2000; i++)
{
s += i.ToString() + t;
}
return s;
}
}
结果是这样的:
如您所见,文本被裁剪并且只显示前 100 行。标签本身(黄色背景)很好,因为我强制高度很大,否则标签的高度也会是同样的长度。
所以,基本上如果你在标签上设置一个很长的文本,它只会展开显示前 100 行,如果你通过 HeightRequest 手动改变它的高度,那么标签会很好,但文本仍然是剪掉了。
这必须与 ListView.Header 实施有关。
在 Android 上,表单的 ListView
是 android.widget.ListView
,其中 ListView 的 header 被设置为包含您的选择的 Container
的 VisualElement
。
由于您使用的表单 Label
是 Android TextView
,因此 100 行文本是在 Android 小部件 class.尝试通过 Forms 的 ListViewRenderer.cs Container OnMeasure 方法设置高度不会覆盖它。
来自ListViewRenderer.cs
int heightSpec = MeasureSpecFactory.MakeMeasureSpec((int)ctx.ToPixels(request.Request.Height), MeasureSpecMode.Exactly);
_child.ViewGroup.Measure(widthMeasureSpec, heightMeasureSpec);
如果您真的需要在 ListView 中显示那么多文本 Header 无需 创建自定义 ListViewRender 并手动操作该 Container 中 TextView 的 SetLines、SetMinLines 和 SetMaxLines,使用 Forms' Editor
(禁用)代替 header 的 VisualElement
:
var label = new Editor
{
BackgroundColor = Color.Yellow,
Text = genLongText(),
MinimumHeightRequest = 10000,
IsEnabled = false
};
您还可以将 header 已禁用 Editor
嵌入 ScrollView
并将其指定为 ListView
Header
,这样您就可以在其中滚动文本Editor
:
var scrollViewHeader = new ScrollView
{
HeightRequest = 200,
Content = label
};