<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          推薦一個(gè)不錯(cuò)的應(yīng)用程序菜單框架

          共 5294字,需瀏覽 11分鐘

           ·

          2022-04-18 00:06

          ????關(guān)注、星標(biāo)公眾號(hào),直達(dá)精彩內(nèi)容

          來源:http://www.80eboy.com/blog/menu_frame

          下面這個(gè)菜單框架也挺不錯(cuò)的,適合新手入門:

          來源:http://www.80eboy.com/blog/menu_frame

          相信很多攻城獅都用過液晶屏,想寫好一點(diǎn)的ui好像不太可能或且花費(fèi)很多時(shí)間,直接寫吧,感覺好像很零碎,coding都怕了。

          下面介紹一個(gè)簡(jiǎn)單易用的菜單框架,你會(huì)發(fā)現(xiàn)它能做多層菜單而且結(jié)果清晰。

          基本原理:

          如上圖液晶顯示一屏我們定義為一個(gè)page,page中的項(xiàng)目定義為item;這樣page就是item的容器了。當(dāng)我們選中其中的一個(gè)item進(jìn)去后是不是又是一個(gè)page呢,如下圖。

          這樣的話每一個(gè)item的下面都對(duì)應(yīng)一個(gè)page,這樣是不是就構(gòu)成一個(gè)多層的菜單了。

          他們是什么關(guān)系呢?

          一個(gè)page中有item,那么用結(jié)構(gòu)體就可以實(shí)現(xiàn)啦;item下面又有page,那么在item中加一個(gè)page的指針指向item對(duì)應(yīng)的page頁。

          前面都是從上到下的,那么怎么返回呢?

          觀察發(fā)現(xiàn)返回就是子page返回父page,這樣在page結(jié)構(gòu)體中假如一項(xiàng)父page的指針不就ok了。

          具體實(shí)現(xiàn)請(qǐng)看源文件。

          左右滑動(dòng)查看全部代碼>>>

          /******************************************************************************************************/
          //主菜單
          //定義Item項(xiàng)?????????????//顯示方式&序號(hào)??項(xiàng)目的名字????項(xiàng)目指向的頁(Page)
          const?struct?Item?main_item[]={?0x00,?"信息",???&SMS_Page,
          ????????0x01,?"設(shè)置",???&Setting_Page,
          ????????0x02,?"版本",???&Version_Page,
          ????????0x03,?"時(shí)間",???&Time_Page,
          ????????0x04,?"狀態(tài)",???0,
          ????????0x05,?"報(bào)警",???0,
          ????????0x06,?"飛信",???0,
          ????????0x07,?"問答",???0
          };
          //定義一個(gè)Page????????父頁?該頁的回調(diào)函數(shù)?該頁的項(xiàng)??????????項(xiàng)的個(gè)數(shù)????
          const?struct?PAGE?mainPage={0,mainPageCallBack,main_item,sizeof(main_item)/sizeof(struct?Item)};
          /*********************************************************************************************************/


          const?struct?PAGE?Version_Page={&mainPage,Version_CallBack,0,0};
          /***************************************************************************************************************/

          //定義Item項(xiàng)??????????????//顯示方式&序號(hào)????項(xiàng)目的名字??????項(xiàng)目指向的頁(Page)
          const?struct?Item?Setting_item[]={?0x10,?"?00.設(shè)0",???0,
          ?????????0x11,?"?01.設(shè)1",???0,
          ?????????0x12,?"?02.設(shè)2",???0,
          ?????????0x13,?"?03.設(shè)3",???0,
          ?????????0x14,?"?04.設(shè)4",???0,
          ?????????0x15,?"?05.設(shè)5",???0,
          ?????????0x16,?"?06.設(shè)6?你好",??0,
          ?????????0x17,?"?07.設(shè)7",???0,
          ?????????0x18,?"?08.設(shè)8",???0,
          ?????????0x19,?"?09.設(shè)9",???0,
          ?????????0x1A,?"?10.設(shè)10",???0
          ?????????};
          const?struct?PAGE?Setting_Page={&mainPage,Setting_CallBack,Setting_item,sizeof(Setting_item)/sizeof(struct?Item)};
          /***************************************************************************************************************/

          const?struct?PAGE?Time_Page={&mainPage,Time_CallBack,0,0};

          /***************************************************************************************************************/
          //定義Item項(xiàng)??????????????//顯示方式&序號(hào)????項(xiàng)目的名字??????項(xiàng)目指向的頁(Page)
          const?struct?Item?SMS_item[]={?
          ?????????0x10,?"?00.",???&SMS_Text_Page,
          ?????????0x11,?"?01.",???&SMS_Text_Page,
          ?????????0x12,?"?02.",???&SMS_Text_Page,
          ?????????0x13,?"?03.",???&SMS_Text_Page,
          ?????????0x14,?"?04.",???&SMS_Text_Page,
          ?????????0x15,?"?05.",???&SMS_Text_Page,
          ?????????0x16,?"?06.",???&SMS_Text_Page,
          ?????????0x17,?"?07.",???&SMS_Text_Page,
          ?????????0x18,?"?08.",???&SMS_Text_Page,
          ?????????0x19,?"?09.",???&SMS_Text_Page,
          ?????????0x1A,?"?10.",???&SMS_Text_Page
          ?????????};

          const?struct?PAGE?SMS_Page={&mainPage,SMS_CallBack,SMS_item,sizeof(Setting_item)/sizeof(struct?Item)};

          Menu.h:

          左右滑動(dòng)查看全部代碼>>>

          #ifndef?_Menu_H_BAB
          #define?_Menu_H_BAB

          #include?"stm32f10x.h"
          #include?"LCD.h"
          #include?"Key.h"

          #define?KEY_Special??255?///<這個(gè)保留用于特別事件

          //菜單調(diào)試,在調(diào)試時(shí)最好定義,可以幫助發(fā)現(xiàn)問題;當(dāng)發(fā)布時(shí)把其置為0可以加快速度
          #define?MENU_DEBUG?1

          void?Menu_Show(void);

          struct?PAGE
          {

          ?const?struct?PAGE?*pParent;
          ?void?(*Function)(u8?key);
          ?const?struct?Item?*pItem;
          ?const?u8?ItemNum;
          };
          struct?Item
          {

          ?/**
          ?高4位作為特殊用途(bit4=1表示列表顯示否則兩列顯示),低4位用于標(biāo)記Item的序號(hào)??\n
          ?如果為列表模式時(shí)*pText的格式為:" xx.string",最前面保留一個(gè)空格用于個(gè)光標(biāo)(>)使用,xx.為兩位序號(hào)不要"."一定要有,string是要顯示的文字,最多能顯示6個(gè)漢字??\n
          ?如果是兩列顯示則pText,即為要顯示的文本(最多2個(gè)漢字)
          ?*/

          ?const?u8?TypeAndIndex;?
          ?const?u8?*pText;
          ?const?struct?PAGE?*pChildrenPage;
          };

          extern?const?struct?PAGE?*pPage;

          void?SetMainPage(const?struct?PAGE?*pMainPage);
          void?ShowMenu(const?struct?PAGE?*pPage);
          void?ShowPage(const?struct?PAGE?*pPage);
          void?ShowParentPage(void);
          void?ShowItemPage(void);
          void?SelPageItem(u8?ItemIndex);
          u8?Menu_GetSelItem(void);

          void?GetShowLst(u8?*pOutMin,u8?*pOutMax);

          void?KeySelItem(u8?key);

          #endif?

          Menu.c:

          左右滑動(dòng)查看全部代碼>>>

          #include?"Menu.h"

          //保存選中的菜單項(xiàng)變量
          static?u8?SelItem=0;

          /**
          用于當(dāng)前LCD列表中顯示著哪幾項(xiàng)
          高4位:最大序號(hào)
          低4為:最小序號(hào)
          */

          static?u8?ListShow=0x00;

          const?struct?PAGE?*pPage;

          void?SelItemOfList(u8?index);

          void?SetMainPage(const?struct?PAGE?*pMainPage)
          {
          ?pPage=pMainPage;
          }
          /**
          獲得當(dāng)前選中的菜單項(xiàng)
          @return?返回菜單序號(hào)
          */

          u8?Menu_GetSelItem(void)
          {
          ?return?SelItem;
          }

          /**
          獲取當(dāng)前顯示列表的范圍
          @param?pOutMin?當(dāng)前顯示的最小序號(hào)
          @param?pOutMax?當(dāng)前顯示的最大序號(hào)
          */

          void?GetShowLst(u8?*pOutMin,u8?*pOutMax)
          {
          ?*pOutMin=ListShow&0x0f;?
          ?*pOutMax=ListShow>>4;
          }
          void?ShowList(u8?min,u8?max)
          {
          ?u8?i=0,index=0;
          ?#if?MENU_DEBUG
          ??if(max-min>3)
          ??{
          ???Lcd_Clr_Scr();
          ???LCD_Write_Str(0,0,"err:ShowList>3");
          ???while?(1);
          ??}
          ??
          ??if?((pPage->pItem[0].TypeAndIndex?&?0x10)==0)///<如果是使用列表方式
          ??{
          ???
          ????Lcd_Clr_Scr();
          ????LCD_Write_Str(0,0,"不是列表類型不能不能列出");
          ????while?(1);?
          ??}
          ?#endif
          ?
          ?Lcd_Clr_Scr();
          ?for?(index=min;index<=max;index++)
          ?{

          ??LCD_Write_Str(i++,0,pPage->pItem[index].pText);
          ?}
          ?ListShow=(max<<4)|min;?///<記錄當(dāng)前顯示的Item
          ?
          }
          /**
          頁顯示

          1.當(dāng)這個(gè)頁有項(xiàng)目(Item)時(shí):顯示Item并同時(shí)選中Item 0???\n
          2.沒有時(shí):會(huì)調(diào)用該P(yáng)age的回調(diào)函數(shù)并傳入KEY_Special?參數(shù)?\n
          @param?pPage?指向一個(gè)page
          */

          void?ShowPage(?const?struct?PAGE?*pPage)
          {
          ?s8?i;
          ?///清屏
          ?Lcd_Clr_Scr();
          ???
          ?if(pPage->pItem==0)?
          ?{
          ??pPage->Function(KEY_Special);
          ??return;?///<如果沒有Item項(xiàng)則不顯示Item,直接返回
          ?}
          ??
          ?if?(pPage->pItem[0].TypeAndIndex?&?0x10)///<如果是使用列表方式
          ?{
          ??ShowList(0,3);
          ??SelItemOfList(0);
          ??pPage->Function(KEY_Special);
          ?}
          ?else
          ?{?
          ??///取出page中的Item并顯示
          ??for?(i=0;iItemNum;i++)
          ??{
          ???if?(i<4)
          ???{
          ????LCD_Write_Str(i,1,pPage->pItem[i].pText);
          ???}
          ???else
          ???{
          ????LCD_Write_Str(i-4,5,pPage->pItem[i].pText);
          ???}
          ???
          ??}
          ??SelPageItem(0);///<選中Item?0
          ??pPage->Function(KEY_Special);
          ?}
          ?
          };

          /**
          顯示父頁(ParentPage)
          */

          void?ShowParentPage(void)
          {
          ?pPage=pPage->pParent;
          ?ShowPage(pPage);
          }

          /**
          顯示項(xiàng)目(Item)下對(duì)應(yīng)的頁(Page)
          */

          void?ShowItemPage(void)
          {
          ?//如果該項(xiàng)下沒有頁,這警告或返回
          ?if?(pPage->pItem[Menu_GetSelItem()].pChildrenPage?==0)
          ?{
          ??#if?MENU_DEBUG
          ???Lcd_Clr_Scr();
          ???LCD_Write_Str(0,0,"該項(xiàng)下無顯示請(qǐng)修正");
          ???while?(1);
          ??#else
          ???return;
          ??#endif?
          ?}
          ?pPage=pPage->pItem[Menu_GetSelItem()].pChildrenPage;?//獲得菜單項(xiàng)(Item)對(duì)應(yīng)的page

          ?ShowPage(pPage);
          }

          /**
          選擇page中的Item項(xiàng)
          @param?ItemIndex?page中Item的索引號(hào)?0~7
          */

          void?SelPageItem(u8?ItemIndex)
          {
          ?///檢查是否有錯(cuò)誤調(diào)用
          #if?MENU_DEBUG

          ?if?(ItemIndex>=8)
          ?{
          ??LCD_Write_Str(0,0,"設(shè)置菜單項(xiàng)溢出");
          ??return;
          ?}
          #endif

          ///清除上次選中的
          ???if?(SelItem<4)
          ???{
          ??LCD_Write_Str(SelItem,0,"??");
          ??LCD_Write_Str(SelItem,3,"??");
          ?
          ???}
          ???else
          ???{
          ??LCD_Write_Str(SelItem-4,4,"??");
          ??LCD_Write_Str(SelItem-4,7,"??");
          ???}
          ///選中這次要選中的??
          ???if?(ItemIndex<4)
          ???{
          ??LCD_Write_Str(ItemIndex,0,"【");
          ??LCD_Write_Str(ItemIndex,3,"】");
          ??SelItem=ItemIndex;
          ???}
          ???else
          ???{
          ??LCD_Write_Str(ItemIndex-4,4,"【");
          ??LCD_Write_Str(ItemIndex-4,7,"】");
          ??SelItem=ItemIndex;
          ???}?
          };
          void?SelItemOfList(u8?index)
          {
          ?u8?max;
          ?u8?min;
          ?
          ?max=ListShow>>4;
          ?min=ListShow&0x0f;
          ?
          ?if?(index>max)?///<超出最大當(dāng)前顯示的序號(hào)
          ?{
          ??
          ??LCD_Write_Str(Menu_GetSelItem()-min,0,"?");
          ??
          ??min+=1;
          ??max+=1;
          ??ShowList(min,max);
          ??ListShow=(max<<4)|min;
          ??
          ??LCD_Write_Str(index-min,0,">");
          ??
          ?}
          ?else?if(index>=min)///<在最小和最大序號(hào)之間
          ?{
          ??LCD_Write_Str(Menu_GetSelItem()-min,0,"?");
          ??LCD_Write_Str(index-min,0,">");
          ?}
          ?else?????///<低于最小當(dāng)前顯示最小序號(hào)
          ?{
          ??LCD_Write_Str(Menu_GetSelItem()-min,0,"?");
          ??
          ??min-=1;
          ??max-=1;
          ??ShowList(min,max);
          ??ListShow=(max<<4)|min;
          ??
          ??LCD_Write_Str(index-min,0,">");
          ?}
          ?SelItem=index;
          }
          void?KeySelItem(u8?key)
          {
          ?s8?index;
          ?if?(pPage->pItem[0].TypeAndIndex?&?0x10)///<如果是使用列表方式
          ?{
          ??switch(key)
          ??{
          ???case?KEY_UP:
          ????index=Menu_GetSelItem()-1;
          ????if(index<0)?break;
          ????
          ????SelItemOfList(index);
          ????break;
          ???case?KEY_Down:
          ????index=Menu_GetSelItem()+1;
          ????if(index>(pPage->ItemNum-1))?break;;
          ????SelItemOfList(index);
          ????break;
          ??}
          ??return;
          ?}
          ?switch(key)
          ?{
          ??case?KEY_UP:
          ???index=Menu_GetSelItem()-1;
          ???if(index<0)?index=pPage->ItemNum-1;
          ???SelPageItem(index);
          ???break;
          ??case?KEY_Down:
          ???index=Menu_GetSelItem()+1;
          ???if(index>(pPage->ItemNum-1))?index=0;
          ???SelPageItem(index);
          ???break;
          ??case?KEY_Left:
          ??case?KEY_Right:?
          ???index=Menu_GetSelItem();
          ???if?(index<4)
          ???{
          ????if((index+4)>(pPage->ItemNum-1))?return;?//右沒有Item項(xiàng),無法選中右邊項(xiàng);所以返回
          ????index+=4;????????//右邊有Item時(shí)把index定位到右邊的Item
          ???}?
          ???else?????index-=4;??????//因?yàn)橛疫呌蠭tem項(xiàng)時(shí),左邊一定有Item項(xiàng);因?yàn)槭前错樞虬才诺?/span>
          ???SelPageItem(index);
          ???break;
          ?}
          }

          篇幅有限,MenuAPP代碼未貼出。

          完整工程代碼獲取方式:

          在微信公眾號(hào)【技術(shù)讓夢(mèng)想更偉大,點(diǎn)擊下方,在后臺(tái)回復(fù)關(guān)鍵字:Menu?,即可獲取。

          ???????????????? ?END ????????????????

          關(guān)注我的微信公眾號(hào),回復(fù)“加群”按規(guī)則加入技術(shù)交流群。

          點(diǎn)擊下面圖片,有星球具體介紹,新用戶有新人優(yōu)惠券,老用戶半價(jià)優(yōu)惠,期待大家一起學(xué)習(xí)一起進(jìn)步。


          點(diǎn)擊“閱讀原文”查看更多分享,歡迎點(diǎn)分享、收藏、點(diǎn)贊、在看。

          瀏覽 28
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  yy6080伦理 | 婷婷丁香激情 | 一级视频在线观看免费 | 国产十八 免费一级A片 | 国产一级黄色A片 |