TabLayout

Struct TabLayout 

Source
pub struct TabLayout { /* private fields */ }
Expand description

A TabLayout displays a horizontal row of tabs

TabLayout is useful for creating tabbed interfaces. It emits ‘itemselected’ events when a tab is clicked, with the tab index as the value.

Implementations§

Source§

impl TabLayout

Source

pub fn new(activity: &mut Activity, parent: Option<i64>) -> Result<Self>

Create a new TabLayout

Source

pub fn id(&self) -> i64

Get the view ID

Examples found in repository?
examples/tab_layout_demo_v2.rs (line 99)
9fn main() -> Result<()> {
10    println!("=== TabLayout 标签页演示 (新库版本) ===\n");
11
12    // 创建连接和 Activity
13    let mut activity = Activity::new(false)?;
14    println!("✓ 连接建立");
15
16    // 创建根布局(垂直)
17    let root = activity.create_linear_layout(None)?;
18    
19    // 创建 TabLayout(在顶部)
20    let tabs = activity.create_tab_layout(Some(root.id()))?;
21    tabs.view().set_linear_layout_params(&mut activity, 0, None)?;
22    tabs.view().set_height(&mut activity, -2)?; // WRAP_CONTENT
23    
24    // 设置标签列表
25    tabs.set_list(&mut activity, &["首页", "消息", "我的"])?;
26    
27    // 创建内容区域
28    let content_area = activity.create_linear_layout(Some(root.id()))?;
29    content_area.view().set_linear_layout_params(&mut activity, 1, None)?; // weight=1 占据剩余空间
30    
31    // 创建三个页面的内容(初始全部隐藏)
32    // 页面1 - 首页
33    let page1 = activity.create_linear_layout(Some(content_area.id()))?;
34    
35    let title1 = activity.create_text_view("📱 首页", Some(page1.id()))?;
36    title1.set_text_size(&mut activity, 28)?;
37    
38    let content1 = activity.create_text_view("\n欢迎使用 TabLayout!\n\n这是首页内容。\n\n☝️ 点击顶部标签切换页面", Some(page1.id()))?;
39    content1.set_text_size(&mut activity, 18)?;
40    
41    // 页面2 - 消息
42    let page2 = activity.create_linear_layout(Some(content_area.id()))?;
43    activity.send(&serde_json::json!({
44        "method": "setVisibility",
45        "params": {
46            "aid": activity.id(),
47            "id": page2.id(),
48            "vis": 8  // GONE initially
49        }
50    }))?;
51    
52    let title2 = activity.create_text_view("💬 消息中心", Some(page2.id()))?;
53    title2.set_text_size(&mut activity, 28)?;
54    
55    let content2 = activity.create_text_view("\n这是第二页\n\n你有 3 条新消息\n\n• 系统通知\n• 好友消息\n• 更新提醒", Some(page2.id()))?;
56    content2.set_text_size(&mut activity, 18)?;
57    
58    // 页面3 - 我的
59    let page3 = activity.create_linear_layout(Some(content_area.id()))?;
60    activity.send(&serde_json::json!({
61        "method": "setVisibility",
62        "params": {
63            "aid": activity.id(),
64            "id": page3.id(),
65            "vis": 8  // GONE initially
66        }
67    }))?;
68    
69    let title3 = activity.create_text_view("👤 个人中心", Some(page3.id()))?;
70    title3.set_text_size(&mut activity, 28)?;
71    
72    let content3 = activity.create_text_view("\n这是第三页\n\n个人信息\n\n• 账号设置\n• 隐私设置\n• 关于我们", Some(page3.id()))?;
73    content3.set_text_size(&mut activity, 18)?;
74    
75    println!("\n✓ 界面创建完成");
76    println!("\n━━━━━━━━━━━━━━━━━━━━━━");
77    println!("提示:");
78    println!("  • 点击顶部标签切换页面");
79    println!("  • 观察页面内容变化");
80    println!("━━━━━━━━━━━━━━━━━━━━━━\n");
81    
82    // 当前选中的标签页
83    let mut current_tab = 0;
84    let pages = [page1.id(), page2.id(), page3.id()];
85    
86    // 事件循环
87    loop {
88        let event = read_message(activity.event_stream())?;
89        let event_type = event["type"].as_str().unwrap_or("");
90        
91        match event_type {
92            "destroy" => {
93                println!("\n✓ Activity 已关闭");
94                return Ok(());
95            }
96            "itemselected" => {
97                // TabLayout 被点击
98                if let Some(selected) = event["value"]["selected"].as_i64() {
99                    if event["value"]["id"].as_i64() == Some(tabs.id()) {
100                        let new_tab = selected as usize;
101                        if new_tab != current_tab && new_tab < 3 {
102                            println!("切换到标签 {}: {}", new_tab, ["首页", "消息", "我的"][new_tab]);
103                            
104                            // 隐藏当前页面
105                            activity.send(&serde_json::json!({
106                                "method": "setVisibility",
107                                "params": {
108                                    "aid": activity.id(),
109                                    "id": pages[current_tab],
110                                    "vis": 8  // GONE
111                                }
112                            }))?;
113                            
114                            // 显示新页面
115                            activity.send(&serde_json::json!({
116                                "method": "setVisibility",
117                                "params": {
118                                    "aid": activity.id(),
119                                    "id": pages[new_tab],
120                                    "vis": 0  // VISIBLE
121                                }
122                            }))?;
123                            
124                            current_tab = new_tab;
125                        }
126                    }
127                }
128            }
129            _ => {}
130        }
131    }
132}
Source

pub fn view(&self) -> &View

Get the underlying View

Examples found in repository?
examples/tab_layout_demo_v2.rs (line 21)
9fn main() -> Result<()> {
10    println!("=== TabLayout 标签页演示 (新库版本) ===\n");
11
12    // 创建连接和 Activity
13    let mut activity = Activity::new(false)?;
14    println!("✓ 连接建立");
15
16    // 创建根布局(垂直)
17    let root = activity.create_linear_layout(None)?;
18    
19    // 创建 TabLayout(在顶部)
20    let tabs = activity.create_tab_layout(Some(root.id()))?;
21    tabs.view().set_linear_layout_params(&mut activity, 0, None)?;
22    tabs.view().set_height(&mut activity, -2)?; // WRAP_CONTENT
23    
24    // 设置标签列表
25    tabs.set_list(&mut activity, &["首页", "消息", "我的"])?;
26    
27    // 创建内容区域
28    let content_area = activity.create_linear_layout(Some(root.id()))?;
29    content_area.view().set_linear_layout_params(&mut activity, 1, None)?; // weight=1 占据剩余空间
30    
31    // 创建三个页面的内容(初始全部隐藏)
32    // 页面1 - 首页
33    let page1 = activity.create_linear_layout(Some(content_area.id()))?;
34    
35    let title1 = activity.create_text_view("📱 首页", Some(page1.id()))?;
36    title1.set_text_size(&mut activity, 28)?;
37    
38    let content1 = activity.create_text_view("\n欢迎使用 TabLayout!\n\n这是首页内容。\n\n☝️ 点击顶部标签切换页面", Some(page1.id()))?;
39    content1.set_text_size(&mut activity, 18)?;
40    
41    // 页面2 - 消息
42    let page2 = activity.create_linear_layout(Some(content_area.id()))?;
43    activity.send(&serde_json::json!({
44        "method": "setVisibility",
45        "params": {
46            "aid": activity.id(),
47            "id": page2.id(),
48            "vis": 8  // GONE initially
49        }
50    }))?;
51    
52    let title2 = activity.create_text_view("💬 消息中心", Some(page2.id()))?;
53    title2.set_text_size(&mut activity, 28)?;
54    
55    let content2 = activity.create_text_view("\n这是第二页\n\n你有 3 条新消息\n\n• 系统通知\n• 好友消息\n• 更新提醒", Some(page2.id()))?;
56    content2.set_text_size(&mut activity, 18)?;
57    
58    // 页面3 - 我的
59    let page3 = activity.create_linear_layout(Some(content_area.id()))?;
60    activity.send(&serde_json::json!({
61        "method": "setVisibility",
62        "params": {
63            "aid": activity.id(),
64            "id": page3.id(),
65            "vis": 8  // GONE initially
66        }
67    }))?;
68    
69    let title3 = activity.create_text_view("👤 个人中心", Some(page3.id()))?;
70    title3.set_text_size(&mut activity, 28)?;
71    
72    let content3 = activity.create_text_view("\n这是第三页\n\n个人信息\n\n• 账号设置\n• 隐私设置\n• 关于我们", Some(page3.id()))?;
73    content3.set_text_size(&mut activity, 18)?;
74    
75    println!("\n✓ 界面创建完成");
76    println!("\n━━━━━━━━━━━━━━━━━━━━━━");
77    println!("提示:");
78    println!("  • 点击顶部标签切换页面");
79    println!("  • 观察页面内容变化");
80    println!("━━━━━━━━━━━━━━━━━━━━━━\n");
81    
82    // 当前选中的标签页
83    let mut current_tab = 0;
84    let pages = [page1.id(), page2.id(), page3.id()];
85    
86    // 事件循环
87    loop {
88        let event = read_message(activity.event_stream())?;
89        let event_type = event["type"].as_str().unwrap_or("");
90        
91        match event_type {
92            "destroy" => {
93                println!("\n✓ Activity 已关闭");
94                return Ok(());
95            }
96            "itemselected" => {
97                // TabLayout 被点击
98                if let Some(selected) = event["value"]["selected"].as_i64() {
99                    if event["value"]["id"].as_i64() == Some(tabs.id()) {
100                        let new_tab = selected as usize;
101                        if new_tab != current_tab && new_tab < 3 {
102                            println!("切换到标签 {}: {}", new_tab, ["首页", "消息", "我的"][new_tab]);
103                            
104                            // 隐藏当前页面
105                            activity.send(&serde_json::json!({
106                                "method": "setVisibility",
107                                "params": {
108                                    "aid": activity.id(),
109                                    "id": pages[current_tab],
110                                    "vis": 8  // GONE
111                                }
112                            }))?;
113                            
114                            // 显示新页面
115                            activity.send(&serde_json::json!({
116                                "method": "setVisibility",
117                                "params": {
118                                    "aid": activity.id(),
119                                    "id": pages[new_tab],
120                                    "vis": 0  // VISIBLE
121                                }
122                            }))?;
123                            
124                            current_tab = new_tab;
125                        }
126                    }
127                }
128            }
129            _ => {}
130        }
131    }
132}
Source

pub fn set_list(&self, activity: &mut Activity, tabs: &[&str]) -> Result<()>

Set the list of tab labels

§Arguments
  • tabs - A slice of strings representing the tab labels
§Example
tab_layout.set_list(activity, &["Page 1", "Page 2", "Page 3"])?;
Examples found in repository?
examples/tab_layout_demo_v2.rs (line 25)
9fn main() -> Result<()> {
10    println!("=== TabLayout 标签页演示 (新库版本) ===\n");
11
12    // 创建连接和 Activity
13    let mut activity = Activity::new(false)?;
14    println!("✓ 连接建立");
15
16    // 创建根布局(垂直)
17    let root = activity.create_linear_layout(None)?;
18    
19    // 创建 TabLayout(在顶部)
20    let tabs = activity.create_tab_layout(Some(root.id()))?;
21    tabs.view().set_linear_layout_params(&mut activity, 0, None)?;
22    tabs.view().set_height(&mut activity, -2)?; // WRAP_CONTENT
23    
24    // 设置标签列表
25    tabs.set_list(&mut activity, &["首页", "消息", "我的"])?;
26    
27    // 创建内容区域
28    let content_area = activity.create_linear_layout(Some(root.id()))?;
29    content_area.view().set_linear_layout_params(&mut activity, 1, None)?; // weight=1 占据剩余空间
30    
31    // 创建三个页面的内容(初始全部隐藏)
32    // 页面1 - 首页
33    let page1 = activity.create_linear_layout(Some(content_area.id()))?;
34    
35    let title1 = activity.create_text_view("📱 首页", Some(page1.id()))?;
36    title1.set_text_size(&mut activity, 28)?;
37    
38    let content1 = activity.create_text_view("\n欢迎使用 TabLayout!\n\n这是首页内容。\n\n☝️ 点击顶部标签切换页面", Some(page1.id()))?;
39    content1.set_text_size(&mut activity, 18)?;
40    
41    // 页面2 - 消息
42    let page2 = activity.create_linear_layout(Some(content_area.id()))?;
43    activity.send(&serde_json::json!({
44        "method": "setVisibility",
45        "params": {
46            "aid": activity.id(),
47            "id": page2.id(),
48            "vis": 8  // GONE initially
49        }
50    }))?;
51    
52    let title2 = activity.create_text_view("💬 消息中心", Some(page2.id()))?;
53    title2.set_text_size(&mut activity, 28)?;
54    
55    let content2 = activity.create_text_view("\n这是第二页\n\n你有 3 条新消息\n\n• 系统通知\n• 好友消息\n• 更新提醒", Some(page2.id()))?;
56    content2.set_text_size(&mut activity, 18)?;
57    
58    // 页面3 - 我的
59    let page3 = activity.create_linear_layout(Some(content_area.id()))?;
60    activity.send(&serde_json::json!({
61        "method": "setVisibility",
62        "params": {
63            "aid": activity.id(),
64            "id": page3.id(),
65            "vis": 8  // GONE initially
66        }
67    }))?;
68    
69    let title3 = activity.create_text_view("👤 个人中心", Some(page3.id()))?;
70    title3.set_text_size(&mut activity, 28)?;
71    
72    let content3 = activity.create_text_view("\n这是第三页\n\n个人信息\n\n• 账号设置\n• 隐私设置\n• 关于我们", Some(page3.id()))?;
73    content3.set_text_size(&mut activity, 18)?;
74    
75    println!("\n✓ 界面创建完成");
76    println!("\n━━━━━━━━━━━━━━━━━━━━━━");
77    println!("提示:");
78    println!("  • 点击顶部标签切换页面");
79    println!("  • 观察页面内容变化");
80    println!("━━━━━━━━━━━━━━━━━━━━━━\n");
81    
82    // 当前选中的标签页
83    let mut current_tab = 0;
84    let pages = [page1.id(), page2.id(), page3.id()];
85    
86    // 事件循环
87    loop {
88        let event = read_message(activity.event_stream())?;
89        let event_type = event["type"].as_str().unwrap_or("");
90        
91        match event_type {
92            "destroy" => {
93                println!("\n✓ Activity 已关闭");
94                return Ok(());
95            }
96            "itemselected" => {
97                // TabLayout 被点击
98                if let Some(selected) = event["value"]["selected"].as_i64() {
99                    if event["value"]["id"].as_i64() == Some(tabs.id()) {
100                        let new_tab = selected as usize;
101                        if new_tab != current_tab && new_tab < 3 {
102                            println!("切换到标签 {}: {}", new_tab, ["首页", "消息", "我的"][new_tab]);
103                            
104                            // 隐藏当前页面
105                            activity.send(&serde_json::json!({
106                                "method": "setVisibility",
107                                "params": {
108                                    "aid": activity.id(),
109                                    "id": pages[current_tab],
110                                    "vis": 8  // GONE
111                                }
112                            }))?;
113                            
114                            // 显示新页面
115                            activity.send(&serde_json::json!({
116                                "method": "setVisibility",
117                                "params": {
118                                    "aid": activity.id(),
119                                    "id": pages[new_tab],
120                                    "vis": 0  // VISIBLE
121                                }
122                            }))?;
123                            
124                            current_tab = new_tab;
125                        }
126                    }
127                }
128            }
129            _ => {}
130        }
131    }
132}
Source

pub fn select_tab(&self, activity: &mut Activity, index: usize) -> Result<()>

Programmatically select a tab

§Arguments
  • index - The zero-based index of the tab to select
§Example
// Select the second tab (index 1)
tab_layout.select_tab(activity, 1)?;

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V