fix.微调了央广网小组件

This commit is contained in:
lincube
2026-06-30 12:21:24 +08:00
parent 135492f935
commit 96c6bde474
2 changed files with 33 additions and 216 deletions

View File

@@ -94,7 +94,7 @@
<StackPanel Grid.Row="1" Spacing="12"> <StackPanel Grid.Row="1" Spacing="12">
<!-- 新闻项 1 --> <!-- 新闻项 1 -->
<Grid x:Name="NewsItem1Grid" <Grid x:Name="NewsItem1Card"
ColumnDefinitions="*,Auto" ColumnDefinitions="*,Auto"
ColumnSpacing="12" ColumnSpacing="12"
Cursor="Hand"> Cursor="Hand">
@@ -102,18 +102,18 @@
Text="Headline" Text="Headline"
Foreground="{DynamicResource TextFillColorPrimaryBrush}" Foreground="{DynamicResource TextFillColorPrimaryBrush}"
FontSize="16" FontSize="16"
FontWeight="SemiBold" FontWeight="Bold"
TextWrapping="Wrap" TextWrapping="Wrap"
TextTrimming="CharacterEllipsis" TextTrimming="CharacterEllipsis"
MaxLines="2" MaxLines="2"
VerticalAlignment="Top" VerticalAlignment="Top"
LineHeight="22" /> LineHeight="24" />
<Border x:Name="News1ImageHost" <Border x:Name="News1ImageHost"
Grid.Column="1" Grid.Column="1"
Width="140" Width="140"
Height="80" Height="80"
CornerRadius="8" CornerRadius="{DynamicResource DesignCornerRadiusXs}"
ClipToBounds="True" ClipToBounds="True"
Background="{DynamicResource CardBackgroundSecondaryBrush}"> Background="{DynamicResource CardBackgroundSecondaryBrush}">
<Image x:Name="News1Image" <Image x:Name="News1Image"
@@ -140,7 +140,7 @@
</Grid> </Grid>
<!-- 新闻项 2 --> <!-- 新闻项 2 -->
<Grid x:Name="NewsItem2Grid" <Grid x:Name="NewsItem2Card"
ColumnDefinitions="*,Auto" ColumnDefinitions="*,Auto"
ColumnSpacing="12" ColumnSpacing="12"
Cursor="Hand"> Cursor="Hand">
@@ -148,18 +148,18 @@
Text="Headline" Text="Headline"
Foreground="{DynamicResource TextFillColorPrimaryBrush}" Foreground="{DynamicResource TextFillColorPrimaryBrush}"
FontSize="16" FontSize="16"
FontWeight="SemiBold" FontWeight="Bold"
TextWrapping="Wrap" TextWrapping="Wrap"
TextTrimming="CharacterEllipsis" TextTrimming="CharacterEllipsis"
MaxLines="2" MaxLines="2"
VerticalAlignment="Top" VerticalAlignment="Top"
LineHeight="22" /> LineHeight="24" />
<Border x:Name="News2ImageHost" <Border x:Name="News2ImageHost"
Grid.Column="1" Grid.Column="1"
Width="140" Width="140"
Height="80" Height="80"
CornerRadius="8" CornerRadius="{DynamicResource DesignCornerRadiusXs}"
ClipToBounds="True" ClipToBounds="True"
Background="{DynamicResource CardBackgroundSecondaryBrush}"> Background="{DynamicResource CardBackgroundSecondaryBrush}">
<Image x:Name="News2Image" <Image x:Name="News2Image"
@@ -184,11 +184,6 @@
</Style> </Style>
</Grid.Styles> </Grid.Styles>
</Grid> </Grid>
<!-- 额外新闻项容器 -->
<StackPanel x:Name="ExtraNewsItemsPanel"
Spacing="12"
IsVisible="False" />
</StackPanel> </StackPanel>
<!-- 状态提示 --> <!-- 状态提示 -->

View File

@@ -49,38 +49,7 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
private readonly LocalizationService _localizationService = new(); private readonly LocalizationService _localizationService = new();
private readonly Bitmap?[] _newsBitmaps = new Bitmap?[2]; private readonly Bitmap?[] _newsBitmaps = new Bitmap?[2];
private readonly List<string?> _newsUrls = []; private readonly List<string?> _newsUrls = [];
private readonly List<ExtraNewsRowVisual> _extraNewsRows = [];
private IReadOnlyList<DailyNewsItemSnapshot> _activeNewsItems = []; private IReadOnlyList<DailyNewsItemSnapshot> _activeNewsItems = [];
private int _renderedNewsCount = 2;
private sealed class ExtraNewsRowVisual
{
public ExtraNewsRowVisual(
Grid rootGrid,
TextBlock titleTextBlock,
Border imageHost,
Image imageControl,
int newsIndex)
{
RootGrid = rootGrid;
TitleTextBlock = titleTextBlock;
ImageHost = imageHost;
ImageControl = imageControl;
NewsIndex = newsIndex;
}
public Grid RootGrid { get; }
public TextBlock TitleTextBlock { get; }
public Border ImageHost { get; }
public Image ImageControl { get; }
public int NewsIndex { get; }
public Bitmap? Bitmap { get; set; }
}
private IRecommendationInfoService _recommendationService = DefaultRecommendationService; private IRecommendationInfoService _recommendationService = DefaultRecommendationService;
private CancellationTokenSource? _refreshCts; private CancellationTokenSource? _refreshCts;
@@ -89,7 +58,6 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
private bool _isAttached; private bool _isAttached;
private bool _isRefreshing; private bool _isRefreshing;
private bool _autoRotateEnabled = true; private bool _autoRotateEnabled = true;
// 删除 _isNightVisual 字段,不再需要手动管理主题
public CnrDailyNewsWidget() public CnrDailyNewsWidget()
{ {
@@ -103,8 +71,8 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
_refreshTimer.Tick += OnRefreshTimerTick; _refreshTimer.Tick += OnRefreshTimerTick;
RefreshButton.Click += OnRefreshButtonClick; RefreshButton.Click += OnRefreshButtonClick;
NewsItem1Grid.PointerPressed += OnNewsItem1PointerPressed; NewsItem1Card.PointerPressed += OnNewsItem1PointerPressed;
NewsItem2Grid.PointerPressed += OnNewsItem2PointerPressed; NewsItem2Card.PointerPressed += OnNewsItem2PointerPressed;
AttachedToVisualTree += OnAttachedToVisualTree; AttachedToVisualTree += OnAttachedToVisualTree;
DetachedFromVisualTree += OnDetachedFromVisualTree; DetachedFromVisualTree += OnDetachedFromVisualTree;
@@ -117,7 +85,6 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
public void ApplyCellSize(double cellSize) public void ApplyCellSize(double cellSize)
{ {
_currentCellSize = Math.Max(1, cellSize); _currentCellSize = Math.Max(1, cellSize);
// 不再需要复杂的自适应逻辑,使用固定标准尺寸
} }
public void SetRecommendationInfoService(IRecommendationInfoService recommendationInfoService) public void SetRecommendationInfoService(IRecommendationInfoService recommendationInfoService)
@@ -153,12 +120,9 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
_refreshTimer.Stop(); _refreshTimer.Stop();
CancelRefreshRequest(); CancelRefreshRequest();
DisposeNewsBitmaps(); DisposeNewsBitmaps();
ClearExtraNewsRows();
UpdateRefreshButtonState(); UpdateRefreshButtonState();
} }
// 删除 OnSizeChanged 和 OnActualThemeVariantChanged不再需要
private async void OnRefreshButtonClick(object? sender, RoutedEventArgs e) private async void OnRefreshButtonClick(object? sender, RoutedEventArgs e)
{ {
if (_isDesignModePreview) if (_isDesignModePreview)
@@ -215,25 +179,6 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
e.Handled = true; e.Handled = true;
} }
private void OnExtraNewsItemPointerPressed(object? sender, PointerPressedEventArgs e)
{
if (_isDesignModePreview)
{
e.Handled = true;
return;
}
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed ||
sender is not Control control ||
control.Tag is not int index)
{
return;
}
TryOpenNewsUrl(index);
e.Handled = true;
}
private async Task RefreshNewsAsync(bool forceRefresh) private async Task RefreshNewsAsync(bool forceRefresh)
{ {
if (!_isAttached || _isRefreshing) if (!_isAttached || _isRefreshing)
@@ -313,7 +258,6 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
_newsUrls.Add(NormalizeHttpUrl(item.Url)); _newsUrls.Add(NormalizeHttpUrl(item.Url));
} }
RenderExtraNewsRows([]);
UpdateNewsInteractionState(); UpdateNewsInteractionState();
StatusTextBlock.IsVisible = false; StatusTextBlock.IsVisible = false;
@@ -345,7 +289,6 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
StatusTextBlock.IsVisible = true; StatusTextBlock.IsVisible = true;
SetNewsBitmap(0, null); SetNewsBitmap(0, null);
SetNewsBitmap(1, null); SetNewsBitmap(1, null);
RenderExtraNewsRows([]);
UpdateNewsInteractionState(); UpdateNewsInteractionState();
} }
@@ -360,7 +303,6 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
StatusTextBlock.IsVisible = true; StatusTextBlock.IsVisible = true;
SetNewsBitmap(0, null); SetNewsBitmap(0, null);
SetNewsBitmap(1, null); SetNewsBitmap(1, null);
RenderExtraNewsRows([]);
UpdateNewsInteractionState(); UpdateNewsInteractionState();
} }
@@ -379,13 +321,7 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
null, null,
"https://example.com/news/preview-2", "https://example.com/news/preview-2",
null, null,
"09:10"), "09:10")
new DailyNewsItemSnapshot(
"Design-time mocks make isolated widget layout tuning much faster.",
null,
"https://example.com/news/preview-3",
null,
"08:55")
]; ];
_newsUrls.Clear(); _newsUrls.Clear();
@@ -401,7 +337,6 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
SetNewsBitmap(0, null); SetNewsBitmap(0, null);
SetNewsBitmap(1, null); SetNewsBitmap(1, null);
RenderExtraNewsRows(_activeNewsItems.Skip(2).ToArray());
UpdateNewsInteractionState(); UpdateNewsInteractionState();
RefreshButton.IsEnabled = false; RefreshButton.IsEnabled = false;
@@ -436,122 +371,6 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
}); });
} }
private void RenderExtraNewsRows(IReadOnlyList<DailyNewsItemSnapshot> extraItems)
{
ClearExtraNewsRows();
if (extraItems.Count == 0)
{
ExtraNewsItemsPanel.IsVisible = false;
_renderedNewsCount = 2;
return;
}
for (var i = 0; i < extraItems.Count; i++)
{
var item = extraItems[i];
var itemIndex = i + 2;
var rowGrid = new Grid
{
ColumnSpacing = 12,
Tag = itemIndex,
Cursor = new Cursor(StandardCursorType.Hand),
IsHitTestVisible = true
};
rowGrid.ColumnDefinitions.Add(new ColumnDefinition(new GridLength(1, GridUnitType.Star)));
rowGrid.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Auto));
rowGrid.PointerPressed += OnExtraNewsItemPointerPressed;
var textBlock = new TextBlock
{
Text = NormalizeCompactText(item.Title),
FontSize = 16,
FontWeight = FontWeight.SemiBold,
TextWrapping = TextWrapping.Wrap,
TextTrimming = TextTrimming.CharacterEllipsis,
MaxLines = 2,
LineHeight = 22,
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top,
IsHitTestVisible = false
};
// 使用动态资源绑定文本颜色
textBlock.Bind(TextBlock.ForegroundProperty,
new Avalonia.Data.Binding("TextFillColorPrimaryBrush")
{
Source = Application.Current!.Resources
});
var imageHost = new Border
{
Width = 140,
Height = 80,
CornerRadius = new CornerRadius(8),
ClipToBounds = true,
IsHitTestVisible = false
};
// 使用动态资源绑定背景色
imageHost.Bind(Border.BackgroundProperty,
new Avalonia.Data.Binding("CardBackgroundSecondaryBrush")
{
Source = Application.Current!.Resources
});
var image = new Image
{
Stretch = Stretch.UniformToFill,
IsHitTestVisible = false
};
imageHost.Child = image;
Grid.SetColumn(imageHost, 1);
rowGrid.Children.Add(textBlock);
rowGrid.Children.Add(imageHost);
ExtraNewsItemsPanel.Children.Add(rowGrid);
_extraNewsRows.Add(new ExtraNewsRowVisual(rowGrid, textBlock, imageHost, image, itemIndex));
}
ExtraNewsItemsPanel.IsVisible = true;
_renderedNewsCount = 2 + extraItems.Count;
}
private void ClearExtraNewsRows()
{
foreach (var row in _extraNewsRows)
{
row.RootGrid.PointerPressed -= OnExtraNewsItemPointerPressed;
if (ReferenceEquals(row.ImageControl.Source, row.Bitmap))
{
row.ImageControl.Source = null;
}
row.Bitmap?.Dispose();
row.Bitmap = null;
}
_extraNewsRows.Clear();
ExtraNewsItemsPanel.Children.Clear();
}
private void SetExtraNewsBitmap(int rowIndex, Bitmap? bitmap)
{
if (rowIndex < 0 || rowIndex >= _extraNewsRows.Count)
{
bitmap?.Dispose();
return;
}
var row = _extraNewsRows[rowIndex];
if (ReferenceEquals(row.ImageControl.Source, row.Bitmap))
{
row.ImageControl.Source = null;
}
row.Bitmap?.Dispose();
row.Bitmap = bitmap;
row.ImageControl.Source = bitmap;
}
private void UpdateRefreshButtonState() private void UpdateRefreshButtonState()
{ {
RefreshButton.IsEnabled = !_isRefreshing && _isAttached; RefreshButton.IsEnabled = !_isRefreshing && _isAttached;
@@ -560,23 +379,12 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
private void UpdateNewsInteractionState() private void UpdateNewsInteractionState()
{ {
var item1Enabled = _newsUrls.Count > 0 && !string.IsNullOrWhiteSpace(_newsUrls[0]); var cards = new[] { NewsItem1Card, NewsItem2Card };
var item2Enabled = _newsUrls.Count > 1 && !string.IsNullOrWhiteSpace(_newsUrls[1]); for (var i = 0; i < cards.Length; i++)
NewsItem1Grid.IsHitTestVisible = item1Enabled;
NewsItem2Grid.IsHitTestVisible = item2Enabled;
NewsItem1Grid.Opacity = item1Enabled ? 1.0 : 0.72;
NewsItem2Grid.Opacity = item2Enabled ? 1.0 : 0.72;
foreach (var row in _extraNewsRows)
{ {
var index = row.NewsIndex; var enabled = i < _newsUrls.Count && !string.IsNullOrWhiteSpace(_newsUrls[i]);
var enabled = index >= 0 && index < _newsUrls.Count && !string.IsNullOrWhiteSpace(_newsUrls[index]); cards[i].IsHitTestVisible = enabled;
row.RootGrid.IsHitTestVisible = enabled; cards[i].Opacity = enabled ? 1.0 : 0.72;
row.RootGrid.Opacity = enabled ? 1.0 : 0.72;
row.RootGrid.Cursor = enabled
? new Cursor(StandardCursorType.Hand)
: new Cursor(StandardCursorType.Arrow);
} }
} }
@@ -676,7 +484,19 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
return; return;
} }
var imageControl = index == 0 ? News1Image : News2Image; var imageControl = index switch
{
0 => News1Image,
1 => News2Image,
_ => null
};
if (imageControl is null)
{
bitmap?.Dispose();
return;
}
var oldBitmap = _newsBitmaps[index]; var oldBitmap = _newsBitmaps[index];
if (ReferenceEquals(imageControl.Source, oldBitmap)) if (ReferenceEquals(imageControl.Source, oldBitmap))
{ {
@@ -695,8 +515,10 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
private void DisposeNewsBitmaps() private void DisposeNewsBitmaps()
{ {
SetNewsBitmap(0, null); for (var i = 0; i < _newsBitmaps.Length; i++)
SetNewsBitmap(1, null); {
SetNewsBitmap(i, null);
}
} }
private void UpdateLanguageCode() private void UpdateLanguageCode()