Android从入门到精通——学习笔记,Chapter05-高级UI组件,Android高级UI组件学习笔记,从入门到精通Chapter 05

马肤

温馨提示:这篇文章已超过444天没有更新,请注意相关的内容是否还可用!

摘要:,,本学习笔记涵盖了Android开发中的Chapter05——高级UI组件。内容从Android UI设计的基础知识开始,逐步深入探讨各种高级UI组件的使用方法和技巧。通过学习,读者可以掌握如何创建具有吸引力和交互性的用户界面,包括自定义视图、布局、动画和高级控件等。本书旨在为初学者提供入门引导,同时为经验丰富的开发者提供进阶技巧,助力从入门到精通Android开发。

Chapter 05 高级UI组件

本章介绍Android开发常用的一些高级UI组件,主要包括列表类组件、切换类组件以及通用组件。本章主要学习一些可以滑动的列表或是切换类的组件,通过此类组件可以实现动态UI界面的效果。

5.1 列表类组件

在Android中提供了两种列表类组件:一种是下拉列表框,通常用于弹出一个下拉菜单供用户选择,用Spinner表示;另一种是列表视图,通常用于实现在一个窗口中只显示一个列表,使用ListView表示。

5.1.1 下拉列表框

Android中提供的下拉列表框(Spinner)通常用于提供一系列列表项供用户进行选择。例如,豆瓣网搜索界面中的搜索类型的下拉列表框。

在Android中,在XML布局文件中通过标记添加下拉列表框,基本语法格式如下:


其中,android:entries为可选属性,用于指定列表项,如果在布局文件中不指定该属性,可以在java代码中通过为其指定适配器的方式指定;android:prompt属性也是可选属性,用于指定下拉列表框的标题。

通常情况下,如果下拉列表框中要显示的列表行是可知的,那么将其保存在数组资源文件中,然后通过数组资源为下拉列表框指定列表项。这样,就可以在不编写Java代码中的情况下实现一个下拉列表框。下面将通过一个小例子(豆瓣网搜索下拉列表框)进行演示,说明如何在不编写Java打码的情况下,在屏幕中添加下拉列表项。

例子:豆瓣网下拉列表框:

(1)布局文件activity_main.xml内容如下:

    
        
        
    
    

(2)编写用于指定列表行的数组资源文件,并将其保存在res\values目录中,这里将其命名为arrays.xml,在该文件中添加一个字符串数组,名称为ctype,内容如下:

resources>
    
        全部
        电影/电视
        图书
        唱片
        小事
        用户
        小组
        群聊
        游戏/应用
        活动
    

(3)主活动MainActivity.java内容如下:

public class MainActivity extends AppCompatActivity {
    Spinner spinner;
    TextView notice;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        spinner = findViewById(R.id.spinner);
        notice = findViewById(R.id.notice);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id) {
                //获取选择项的值
                String result = parent.getItemAtPosition(position).toString();
                //显示被选中的值
                notice.setText(result);
            }
            @Override
            public void onNothingSelected(AdapterView parent) {
            }
        });
    }
}

Android从入门到精通——学习笔记,Chapter05-高级UI组件,Android高级UI组件学习笔记,从入门到精通Chapter 05 第1张

在使用下拉列表框时,如果不在布局文件中直接为其指定要显示的列表项,也可以通过为其指定适配器的方式指定。下面仍然以上述豆瓣网搜索页面例子介绍通过指定适配器的方式指定列表项的方法。

为下拉列表框指定适配器,通常分为一下3个步骤:

(1)创建一个适配器对象,通常使用ArrayAdapter类。首先需要创建一个一维的字符串数组用于保存要显示的列表项,然后使用ArrayAdapter类的构造方法ArrayAdapter(Context context, int textViewResourceId, T[] objects)实例化一个ArrayAdapter类的实例,具体代码如下:

String[] ctype = new String[] {
            "全部", "电影", "图片", "唱片", "小事",
            "用户", "小组", "群聊", "游戏", "活动"
    };
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item);

(2)为适配器设置列表框下拉时的选项样式,具体代码如下:

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

(3)将适配器与下拉列表框关联,具体代码如下:

spinner.setAdapter(adapter);
5.1.2 列表视图

列表视图(ListView)是Android中最常用的一种视图,它以垂直列表的形式列出需要显示的列表项。例如,卫星通讯界面中的联系人列表,以及QQ的图片浏览设置界面。

在Android中,可以通过在XML布局文件中使用标记添加列表视图,其基本语法格式如下:


ListView组件支持的常用的XML属性如下表所示:

ListView组件支持的XML属性
XML属性描述
android:divider用于为列表视图设置为分隔条,既可以用颜色分割,也可以用Drawable资源分隔
android:dividerHeight用于设置分隔条的高度
android:entries用于通过数组资源位ListView指定列表项
android:footerDividersEnable用于设置是否在footer View(底部视图)之间绘制分隔条,默认值为true,设置为false时,表示不绘制。使用该属性时,需要通过ListView组件提供的addFooterView()方法为ListView设置footer View
android:headerDividersEnable用于设置是否在header View(头部视图)之间绘制分隔条,默认值为true,设置为false时,表示不绘制。使用该属性时,需要通过ListView组件提供的addHeaderView()方法为ListView设置header View

例如,在布局文件中添加一个列表视图,并通过数组资源为其设置列表项,具体代码如下:

同Spinner一样,ListView也可以通过两种方式指定列表项:一种是将定义的数组资源保存至数组资源文件中,在布局文件中通过ListView的entries属性进行指定;另一种是通过为其设置Adapter来指定需要显示的列表项。

通过Adapter来为ListView指定要显示的列表项,可以分为以下两个步骤:

(1)创建Adapter对象。对于纯文字的列表项,通常使用ArrayAdapter对象。创建ArrayAdapter对象通常可以有两种方式:一种是通过数组资源文件创建;另一种是通过在Java文件中使用字符串数组创建。这与Spinner下拉列表框中介绍的创建ArrayAdapter对象基本相同,所不同的就是在创建对象时,指定列表项的外观形式。在AndroidAPI中默认提供了一些用于设置外观形式的布局文件,通过这些布局文件,可以很方便地指定ListView的外观形式。常用的布局文件有以下几个:

  1. simple_list_item_1:每个列表项都是一个普通的文本。
  2. simple_list_item_2:每个列表项都是一个普通的文本(字体略大)。
  3. simple_list_item_checked:每个列表项都有一个已选中的列表项。
  4. simple_list_item_multiple_choice:每个列表项都是带复选框的文本。
  5. simple_list_item_single_choice:每个列表项都是带单选按钮的文本。

(2)将创建的适配器对象与ListView相关联,可以通过ListView对象的setAdapter()方法实现,具体代码如下:

listView.setAdapter(adapter); //将适配器与ListView关联

下面通过一个实例(模拟支付宝朋友列表)进行演示:

(1)布局文件activity_main.xml的内容如下:

    
    

(2)在新建项目中的res\layout目录下右击新建一个布局文件,命名为item,用来显示图片、名称以及信息内容,具体代码如下:

    
    
        
        
    

(3)打开主活动MainActivity.java,定义图标数组、名字数组、信息数组。

(4)在主活动的onCreate()方法中,首先获取布局文件中添加的ListView,然后创建一个List集合,通过for循环将图标、名字、信息放到Map中,并添加到List集合中。

(5)创建SimpleAdapter适配器,并且将适配器与ListView关联,为ListView创建监听事件,然后用过getItemAtPosition()方法获取选中的值,最后通过TextView将获取的值显示出来。

主活动MainActivity.java的具体内容如下:

public class MainActivity extends AppCompatActivity {
    ListView listView;
    TextView notice;
    int[] icons = {
            R.drawable.icon_1, R.drawable.icon_2, R.drawable.icon_3,
            R.drawable.icon_4, R.drawable.icon_5, R.drawable.icon_6,
            R.drawable.icon_7, R.drawable.icon_8, R.drawable.icon_9,
            R.drawable.icon_10, R.drawable.icon_11
    };
    //名字数组
    private String[] names = {
            "赵...","孙...","李...","周...",
            "吴...","郑...","王...","冯...",
            "陈...","卫...","沈..."
    };
    //信息数组
    private String[] infos = {
            "人之所以能,是相信能。","世上没有绝望的处境,只有对处境绝望的人。",
            "大多数人想要改造这个世界,但却罕有人想改造自己。", "莫找借口失败,只找理由成功",
            "每一发奋努力的背后,必有加倍的赏赐。","人生伟业的建立 ,不在能知,乃在能行。",
            "理想犹如太阳,吸引地上所有的泥水。","沉思的人有一个目标,幻想的人却没有。",
            "心有多大,世界就有多大!", "微笑向阳,无畏悲伤。",
            "有多大的思想,才有多大的能量。",
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView);
        notice = findViewById(R.id.notice);
        List listItems = new ArrayList();
        //通过for循环将图片id和列表项文字放到Map中,并添加到List集合中
        for(int i = 0; i  

Android从入门到精通——学习笔记,Chapter05-高级UI组件,Android高级UI组件学习笔记,从入门到精通Chapter 05 第2张

5.2 切换类组件

本节将介绍如何使用ViewFlipped实现组件之间的切换,然后介绍翻页组件ViewPager配合适配器PagerAdapter的用法以及翻页标题栏PagerTabStrip的用法。下面将对这3种切换类组件进行详细的介绍。

5.2.1 翻页组件(ViewPager)

ViewPager是由Android v4包提供的一个组件,它是ViewGroup的子类,所以它也是一个容器类,可以在其中添加其他的view类。ViewPager需要一个PagerAdapter适配器给它提供数据,它使用的监听器是OnPageChangeListener,用于监听页面切换的事件。在Android中,该组件经常被使用在左右滑动时显示多个页面的运行效果。例如,App中的引导页面,以及京东商城中自动轮播的广告都可以使用ViewPager来实现。

在XML布局文件中添加ViewPager的基本语法格式如下:

 

下面对ViewPager的重要方法进行介绍:

  1. PageAdapter:ViewPager的适配器。创建该对象时需要重写它的4个方法,具体方法如下:
    1. instantiateItem():将当前视图添加到视图容器中并返回当前所显示的视图。
    2. destroyItem():从视图容器中移出指定位置的页面。
    3. getCount():可用滑动页面的数量。
    4. isViewFromObject():确定页面视图是否与返回的对象相关联,返回view == object即可。
  2. ViewPager.OnPageChangeListener:页面切换时的监听事件,其中需要实现3个方法:
    1. onPageScollStateChanged():在翻译状态发生改变时调用。
    2. onPageScolled():在翻页过程中该方法被调用。
    3. onPageSelected():当页面被选中时该方法被调用。

下面通过一个实例(模拟App引导界面)进行演示:

(1)在主活动MainActivity的布局文件activity_main.xml的布局管理器修改为相对布局管理器,并删除TextView组件,增加ViewPager组件用于实现引导页面的切换,具体代码如下:

    
    

(2)在java/com.example目录中创建一个新的Activity,名称为MainActivity2,并且在其布局文件activity_main2.xml中添加主界面2的背景图片

(3)在res\layout目录中对应引导页面的页数创建名称为layout1.xml、layout2.xml …,并设置对应的背景图片,同时在最后一个页面布局文件中设置一个Button按钮用于启动界面2,其具体代码如下:

    

(4)修改MainActivity.java文件内容,加载需要显示在页面中的布局文件,最后将所有页面添加在数组列表中并且为ViewPager指定所使用的适配器,修改后的文件内容如下:

public class MainActivity extends AppCompatActivity {
    private View view1, view2, view3, view4; //4个页面视图
    private List viewList; //保存页面的数组列表
    private ViewPager viewPager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LayoutInflater lf = LayoutInflater.from(this); //获取布局填充器
        viewPager = findViewById(R.id.viewPager);
        view1 = lf.inflate(R.layout.layout1, null);
        view2 = lf.inflate(R.layout.layout2, null);
        view3 = lf.inflate(R.layout.layout3, null);
        view4 = lf.inflate(R.layout.layout4, null);
        viewList = new ArrayList();
        viewList.add(view1);
        viewList.add(view2);
        viewList.add(view3);
        viewList.add(view4);
        PagerAdapter adapter = new PagerAdapter() {
            //获取页面个数
            @Override
            public int getCount() {
                return viewList.size();
            }
            //确定页面视图是否与返回的对象相关联
            @Override
            public boolean isViewFromObject( View view,  Object object) {
                return view == object;
            }
            //返回当前所显示的视图
            @Override
            public Object instantiateItem( ViewGroup container, int position) {
                container.addView(viewList.get(position));
                return viewList.get(position);
            }
            //从视图容器中移出指定位置的页面
            @Override
            public void destroyItem( ViewGroup container, int position, Object object) {
                container.removeView(viewList.get(position));
            }
        };
        viewPager.setAdapter(adapter);
    }
    public void onEvent(View view) {
        Intent intent = new Intent(MainActivity.this, MainActivity2.class);
        startActivity(intent);
    }
}

Android从入门到精通——学习笔记,Chapter05-高级UI组件,Android高级UI组件学习笔记,从入门到精通Chapter 05 第3张

5.2.2 翻页的标题栏(PagerTabStrip)

ViewPager还有两个比较好的搭档,分别是PagerTitleStrip类和PagerTabStrip类。PagerTitleStrip类直接继承自ViewGroup类,而PagerTabStrip是PagerTitleStrip的子类,所以这两个类也是容器类。二者都是可以实现在ViewPager页面上方显示标题文字,不同的是PagerTitleStrip只能显示单纯的标题文字,而PagerTabStrip类似于选项卡,标题文字下面有横线,单击或者左右滑动都可以切换标题文字所对应的页面。

在XML布局文件中添加PagerTabStrip时,必须是ViewPager标签的子标签,基本语法格式如下:

    
    
    

下面对PagerTabStrip类的常用方法进行介绍:

  1. setDrawFullUnderline:参数为布尔类型,true为显示标题文字底部的长横线,false为不显示。
  2. setTabIndicatorColor:设置标题文字指示条的颜色。
  3. setTextColor:设置标题文字的颜色。
  4. setTextSize:设置标题文字的大小。

在标题栏中显示文字时需要重写PagerAdapter中的getPageTitle()方法,代码示例如下:

//设置标题文字
@Override
public CharSequence getPageTitle(int position) {
	return tabList.get(position);
}

下面通过一个实例(根据ViewPager例子修改)来进行演示:

布局文件activity_main.xml内容如下:

    
        
        
        
    

主活动MainActivity.java内容如下:

public class MainActivity extends AppCompatActivity {
    private List pageList = new ArrayList();
    private List tabList = new ArrayList();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
        View view1 = LayoutInflater.from(getApplicationContext()).inflate(R.layout.layout1, null);
        View view2 = LayoutInflater.from(getApplicationContext()).inflate(R.layout.layout2, null);
        View view3 = LayoutInflater.from(getApplicationContext()).inflate(R.layout.layout3, null);
        View view4 = LayoutInflater.from(getApplicationContext()).inflate(R.layout.layout4, null);
        pageList.add(view1);
        pageList.add(view2);
        pageList.add(view3);
        pageList.add(view4);
        tabList.add("Page1");
        tabList.add("Page2");
        tabList.add("Page3");
        tabList.add("Page4");
        PagerAdapter adapter = new PagerAdapter() {
            @Override
            public int getCount() {
                return pageList.size();
            }
            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }
            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                container.addView(pageList.get(position));
                return pageList.get(position);
            }
            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView(pageList.get(position));
            }
            @Nullable
            @Override
            public CharSequence getPageTitle(int position) {
                return tabList.get(position);
            }
        };
        viewPager.setAdapter(adapter);
    }
}

Android从入门到精通——学习笔记,Chapter05-高级UI组件,Android高级UI组件学习笔记,从入门到精通Chapter 05 第4张

5.3 通用组件

在Android中,提供了用于为其他组件添加滚动条的滚动视图,用ScrollView表示。另外,还提供了选项卡,它主要涉及了3个组件。分别为:TabHost,TabWidget和FrameLayout。其中,TabHost表示承载选项卡的容器;TabWidget表示显示选项卡栏,主要用于当用于选择一个选项卡时,向父容器对象TabHost发送一个消息;FrameLayout是用于指定选项卡内容的。其次还有搜索框(SearchView)用于搜索相关数据,下面分别进行介绍。

5.3.1 滚动视图

在默认情况下,当窗体中的内容比较多而一屏显示不下时,超出的部分将不能被用户所看到。因为Android的布局管理器本身没有提供滚动屏幕的功能。如果要让其滚动,就需要使用混动视图(ScrollView),这样用户可以通过滚动视图查看完整的内容。例如,今日头条的新闻界面就应用了滚动视图。

滚动视图时android.widget.FrameLayout(帧布局管理器的子类)。因此,在滚动视图中,可以添加任何要放入其中的组件。但是,一个滚动视图只能放置一个组件。如果想要放置多个,可以在滚动视图中放置一个布局管理器,再将要放置的其他多个组件放置到该布局管理器中。在滚动视图中,使用比较多的是线性布局管理器。

说明:滚动视图ScrollView只支持垂直滚动。如果想要实现水平滚动,可以使用水平滚动视图(HorizontalScrollView)来实现。

在Android中,可以使用两种方法向屏幕中添加滚动视图:一种是通过在XML布局文件中使用标记添加;另一种是在Java文件中通过关键字new创建出来。

下面通过一个实例来介绍如何通过new关键字创建滚动视图:

布局文件activity_main.xml内容如下:

文件res\values\strings.xml文件内容如下:

    ScrollView
    Java Web  编程词典(个人版)主干目录
入门训练营\n
  第1部分   从零开始\n
      第1课   第 1 课  搭建开发环境\n
          第1讲   课堂讲解\n
          第2讲   照猫画虎——基本功训练\n
          第3讲   情景应用——拓展与实践\n
      第2课   第 2 课  JSP中的Java程序\n
          第4讲   课堂讲解\n
          第5讲   照猫画虎——基本功训练\n
          第6讲   情景应用——拓展与实践\n
      第3课   第 3 课  HTML语言与CSS样式\n
          第7讲   课堂讲解\n
          第8讲   照猫画虎——基本功训练\n
          第9讲   情景应用——拓展与实践\n
      第4课   第 4 课  JavaScript脚本语言\n
          第10讲   课堂讲解\n
          第11讲   照猫画虎——基本功训练\n
          第12讲   情景应用——拓展与实践\n
      第5课   第 5 课  掌握JSP语法\n
          第13讲   课堂讲解\n
          第14讲   照猫画虎——基本功训练\n
          第15讲   情景应用——拓展与实践\n
      第6课   第 6 课  使用JSP内置对象\n
          第16讲   课堂讲解\n
          第17讲   照猫画虎——基本功训练\n
          第18讲   情景应用——拓展与实践\n

主活动MainActivity.java内容如下:

public class MainActivity extends AppCompatActivity {
    LinearLayout linearLayout1, linearLayout2;
    ScrollView scrollView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        linearLayout1 = findViewById(R.id.ll); //获取布局管理器
        linearLayout2 = new LinearLayout(this); //创建一个新的布局管理器
        linearLayout2.setOrientation(LinearLayout.VERTICAL); //设置为纵向排列
        scrollView = new ScrollView(this); //创建滚动视图组件
        linearLayout1.addView(scrollView); //默认布局中添加滚动视图组件
        scrollView.addView(linearLayout2); //滚动视图组件中添加新建布局
        ImageView imageView = new ImageView(this);
        imageView.setImageResource(R.mipmap.cidian);
        TextView textView = new TextView(this);
        textView.setText(R.string.dictionary);
        linearLayout2.addView(imageView);
        linearLayout2.addView(textView);
    }
}

Android从入门到精通——学习笔记,Chapter05-高级UI组件,Android高级UI组件学习笔记,从入门到精通Chapter 05 第5张

说明:在默认情况下滚动条不显示,向上拖动后方可显示,停止拖动后滚动条消失。

5.3.2 选项卡

选项卡用于实现一个多标签页的用户界面,通过它可以将一个复杂的对话框分割成若干个标签页,实现对信息的分类显示和管理。使用该组件不仅可以使界面简洁大方,还可以有效地减少窗体的个数。例如,微信的表情包商店界面,报读贴吧的进吧界面。

在Android中,使用选项卡不能通过某一个具体的组件在XML布局文件中添加。通常需要按照以下步骤实现:

  1. 在布局文件中添加实现选项卡所需的TabHost、TabWidget和FrameLayout组件。
  2. 编写各标签页中要显示内容所对应的XML布局文件。
  3. 在Activity中,获取并初始化TabHost组件。
  4. 为TabHost对象添加标签页。

下面通过一个实例(模拟微信表情商店的选项卡)进行演示:

(1)在主活动布局文件activity_main.xml中添加TabHost、TabWidget和FrameLayout组件,其内容如下:

    
        
        
        
    

说明:在应用XML布局文件添加选项卡时,必须使用系统的id来为各组件指定id属性,否则将出现异常。

(2)添加标签页的XML布局文件:

第一个标签页的XML布局文件tab1.xml内容如下:

    

第二个标签页的XML布局文件tab2.xml内容如下:

    
        
    

(3)主活动文件MainActivity.java文件内容如下:

public class MainActivity extends AppCompatActivity {
    private TabHost tabHost;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tabHost = findViewById(R.id.tabHost); //获取
        tabHost.setup(); //初始化
        LayoutInflater inflater = LayoutInflater.from(this);
        inflater.inflate(R.layout.tab1, tabHost.getTabContentView());
        inflater.inflate(R.layout.tab2, tabHost.getTabContentView());
        tabHost.addTab(tabHost.newTabSpec("tab1")
                .setIndicator("精选表情")
                .setContent(R.id.linearLayout2)); //添加第一个标签页
        tabHost.addTab(tabHost.newTabSpec("tab2")
                .setIndicator("投稿表情")
                .setContent(R.id.frameLayout)); //添加第二个标签页
    }
}

Android从入门到精通——学习笔记,Chapter05-高级UI组件,Android高级UI组件学习笔记,从入门到精通Chapter 05 第6张


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码