Android基于高德SDK的开发——自定义地图主题样式(悬浮按钮+底部弹窗)_android 高德地图上悬浮控件-程序员宅基地

技术标签: 安卓  android  map  

日常的地图使用中,平台一般只会给我们提供地图的标准样式,造成了一定程度上的审美疲劳,那么如何实现地图的自定义样式呢?本文使用Android Studio 4.1,给开发者提供了一个基于高德地图SDK进行地图样式设置的方法,在高德平台提供的自定义地图支持基础上,通过界面悬浮按钮+底部弹窗的方式,给用户更人性化的更换地图样式选择。

一、实现效果

实现效果:1、在地图主界面显示一个可移动、可扩展的悬浮按钮。点击按钮后可以弹出五个子按钮。
SuspendButtonLayout悬浮扩展按钮

2、点击其中一个子按钮,在底部弹出滑动表单,给用户提供几种可选择的地图样式。图为标准样式->马卡龙样式。

在这里插入图片描述
3、图为马卡龙样式->草木灰样式。
在这里插入图片描述
流程图示意:
flow chart

二、高德提供的自定义地图样式下载和使用

2.1自定义地图样式下载

对于自定义地图样式,高德提供了一些支持,可以点击高德自定义地图 查看详情。
下面简单描述一下绘制自定义地图或使用高德地图提供的模板的流程。
首先,在高德开放平台中注册登录并申请一个KEY(注意:一个地图APP只能对应一个KEY),将鼠标移动到在右上角的“我的”头像上,出现下拉框选项,选择自定义地图平台。
在这里插入图片描述
可以看到高德已经给我们提供了一些模板,我们可以在模板的基础之上进行编辑。点开任意一个模板,它就加入到了“我的自定义地图”中。此处以“马卡龙”模板作为示例。开发者可以调整河流、陆地等的颜色。
在这里插入图片描述
本示例中选用了标准、马卡龙、草色青和极夜蓝四种样式。编辑好后,点击使用与分享。
在这里插入图片描述
选择Android->离线调用地图样式->下载离线文件。(这里选择的SDK版本对应的是你下载的高德SDK版本)
在这里插入图片描述
在这里插入图片描述
下载后,将zip解压缩,每个样式都能得到style.data和style_extra.data两个文件。将每个文件重命名为对应的样式名称,以作区分。
standard-标准;macaron-马卡龙;grass-草木青;darkblue-极夜蓝。
在这里插入图片描述

2.2 在Android中的离线调用

首先在目录下建立一个assets文件夹。右键new->folder->assets folder即可。
在这里插入图片描述
然后,将上面下载并重命名好的8个样式文件放在assets文件夹中。

在这里插入图片描述
最后,就可以进行调用啦。本示例中新建了一个Mapui.java类将离线文件的调用方法进行封装。

//设置地图样式类
public class Mapui {
    

    //地图自定义样式数据文件路径
    public static String style_macaron = "style_macaron.data";
    public static String style_extra_macaron = "style_extra_macaron.data";
    public static String style_grass = "style_grass.data";
    public static String style_extra_grass = "style_extra_grass.data";
    public static String style_darkblue = "style_darkblue.data";
    public static String style_extra_darkblue = "style_extra_darkblue.data";
    public static String style_standard = "style_standard.data";
    public static String style_extra_standard = "style_extra_standard.data";

    public static void setAssetsStyle(AMap aMap, Context context, String style, String style_extra) {
    
        byte[] buffer1 = null;
        byte[] buffer2 = null;
        InputStream is1 = null;
        InputStream is2 = null;
        try {
    
            is1 = context.getAssets().open(style);
            int lenght1 = is1.available();
            buffer1 = new byte[lenght1];
            is1.read(buffer1);
            is2 = context.getAssets().open(style_extra);
            int lenght2 = is2.available();
            buffer2 = new byte[lenght2];
            is2.read(buffer2);
        } catch (IOException e) {
    
            e.printStackTrace();
        } finally {
    
            try {
    
                if (is1 != null)
                    is1.close();
                if (is2 != null)
                    is2.close();
            } catch (IOException e) {
    
                e.printStackTrace();
            }
        }
        CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions();
        customMapStyleOptions.setEnable(true);
        customMapStyleOptions.setStyleData(buffer1);
        customMapStyleOptions.setStyleExtraData(buffer2);
        aMap.setCustomMapStyle(customMapStyleOptions);
    }
}

三、SuspendButtonLayout悬浮扩展按钮的使用

有了自定义地图样式的封装类(输出),我们还需要有一个可以调用它的方法(输入)。因为该示例APP中除了自定义地图,还有其他基于高德SDK的功能,因此我考虑使用SuspendButtonLayout这样一个悬浮在地图上的可扩展按钮。
需要注意的是,SuspendButtonLayout是由AndroidX提供的(AndroidX是Google 2018 IO 大会推出的新扩展库,主要是对Android 支持库做了重大改进),而CSDN上大多数关于悬浮按钮的博客,都是使用了Android 支持的FloatingtActionButton。使用了AndroidX就不能同时使用Android。可在本文最后的参考博客中阅览二者的区别。

3.1 导入依赖包

在build.gradle(:app)中的dependencies中,加入一行:

implementation 'com.laocaixw.suspendbuttonlayout:suspendbuttonlayout:1.0.3'

3.2 xml布局

在MainActivity的xml布局中,主要含有两个组成部分:地图和悬浮按钮。

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:suspend="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.amap.api.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <com.laocaixw.layout.SuspendButtonLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        suspend:distance="80dp"
        suspend:imageSize="50dp"
        suspend:marginY="100dp"
        suspend:number="5"
        suspend:imageMainOpen="@mipmap/suspend_main_open"
        suspend:imageMainClose="@mipmap/ic_closed"
        suspend:image1="@mipmap/ic_album"
        suspend:image2="@mipmap/ic_random"
        suspend:image3="@mipmap/ic_set_style"
        suspend:image4="@mipmap/ic_ui_setting"
        suspend:image5="@mipmap/suspend_5">

    </com.laocaixw.layout.SuspendButtonLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

此处改写了image的图片样式(详见:五、Android图标库的使用以及自定义图标),默认状态如下,可阅览文末的参考文档:

 <com.laocaixw.layout.SuspendButtonLayout 
  android:id="@+id/layout" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  suspend:distance="80dp" 
  suspend:imageSize="50dp" 
  suspend:marginY="100dp" 
  suspend:number="6" 
  suspend:imageMainOpen="@mipmap/suspend_main_open" 
  suspend:imageMainClose="@mipmap/suspend_main_close" 
  suspend:image1="@mipmap/suspend_1" 
  suspend:image2="@mipmap/suspend_2" 
  suspend:image3="@mipmap/suspend_3" 
  suspend:image4="@mipmap/suspend_4" 
  suspend:image5="@mipmap/suspend_5" 
  suspend:image6="@mipmap/suspend_6"> 
  
  </com.laocaixw.layout.SuspendButtonLayout> 

以上各属性:

distance=“80dp” // 按钮打开后,主按钮和子按钮的距离
imageSize=“50dp” // 按钮大小,所占区域的边长
marginY=“100dp” // 与上下边缘距离,下图中黄色部分的高度
number=“6” // 展开的子按钮的数量,可以是3-6个
imageMainOpen="@mipmap/suspendMainOpen" // 中间按钮展开时的图片资源
imageMainClose="@mipmap/suspendMainClose" // 中间按钮关闭时的图片资源
image1="@mipmap/suspend_1" // 子按钮的图片资源,image1~image6

3.3 在activity中的调用

在MainActivity的onCreate()中使用SuspendButtonLayout。此处只写了5个扩展出的子按钮中第3个按钮自定义地图样式的响应方法,点击其他按钮只会出现一个Toast。

		public String[] suspendChildButtonInfo = {
    "相册", "随机地点", "自定义地图样式", "ui显示设置", "个人中心"};
		
		//可扩展悬浮按钮
        final SuspendButtonLayout suspendButtonLayout = (SuspendButtonLayout) findViewById(R.id.layout);
        suspendButtonLayout.setPosition(true, 90);
        suspendButtonLayout.setOnSuspendListener(new SuspendButtonLayout.OnSuspendListener() {
    
            @Override
            public void onButtonStatusChanged(int status) {
    
            }

            @Override
            public void onChildButtonClick(int index) {
    
                switch (index)
                {
    
                    /**
                     * 相册
                     */
                    case 1:
                        break;

                    /**
                     * 随机地点
                     */
                    case 2:
                        break;

                    /**
                     * 更改地图主题样式
                     */
                    case 3:
                        bottomSheetDialog = new MyBottomSheetDialog(MapActivity.this, aMap);
                        bottomSheetDialog.setContentView(R.layout.bottom_sheet_dialog_layout);
                        bottomSheetDialog.show();
                        break;

                    /**
                     * 更改ui显示设置
                     */
                    case 4:

                        break;

                    /**
                     * 用户个人中心
                     */
                    case 5:
                        break;

                }
                Toast.makeText(MapActivity.this, "您点击了【"
                        + suspendChildButtonInfo[index - 1] + "】按钮!", Toast.LENGTH_SHORT).show();
            }
        });
/**  
 * suspendButtonLayout.hideSuspendButton(); // 隐藏按钮 
  suspendButtonLayout.showSuspendButton(); // 显示按钮 
 
  suspendButtonLayout.openSuspendButton(); // 展开按钮 
  suspendButtonLayout.closeSuspendButton(); // 关闭按钮 
 
  suspendButtonLayout.setMainCloseImageResource(R.mipmap.suspend_main_close); // 设置关闭时,主按钮的图片 
  suspendButtonLayout.setMainOpenImageResource(R.mipmap.suspend_main_open); // 设置展开时,主按钮的图片 
 
  // 设置按钮位置。isRight:true在右边,false在左边;stayPosY:在'按钮停留区域'从上往下,值为从0到100。 
  suspendButtonLayout.setPosition(isRight, stayPosY); */ 

四、自定义BottomSheetDialog底部滑出表单的使用

点击了扩展出的子按钮后,我希望在界面可以滑出一个底部弹窗,以便用户完成上述几种样式的选择。因此选用了继承BottomSheetDialog,创建了一个自定义的MyBottomSheetDialog类。

4.1 导入依赖包

同样地,进行依赖的导入:

implementation 'com.google.android.material:material:1.2.1'

4.2 xml布局

创建一个新的xml文件,命名为bottom_sheet_dialog_layout.xml。这个布局构建得不太完美,在虚拟设备上是每个按钮占用宽度的1/4大小,但在我的手机上显示不全(如开头效果图所示)。

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|center"
    android:background="@android:color/white"
    android:foreground="?android:attr/selectableItemBackground"
    android:orientation="horizontal"
    android:padding="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="15dp"
        android:paddingRight="15dp">

        <Button
            android:id="@+id/tv_dialog_cancel"
            android:layout_width="50dp"
            android:layout_height="10dp"
            android:layout_gravity="center"
            android:background="@color/gray"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:minHeight="30dp"
            android:text="地图主题"
            android:textColor="@color/black"/>

        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:orientation="horizontal">

            <TableRow
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <Button
                    android:id="@+id/btn_standard"
                    style="@style/Widget.AppCompat.Button.Borderless.Colored"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:gravity="center"
                    android:minHeight="48dp"
                    android:background="@mipmap/standard" />

                <Button
                    android:id="@+id/btn_macaron"
                    style="@style/Widget.AppCompat.Button.Borderless.Colored"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:gravity="center"
                    android:minHeight="48dp"
                    android:background="@mipmap/macaron" />

                <Button
                    android:id="@+id/btn_grass"
                    style="@style/Widget.AppCompat.Button.Borderless.Colored"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:gravity="center"
                    android:minHeight="48dp"
                    android:background="@mipmap/grass" />

                <Button
                    android:id="@+id/btn_darkblue"
                    style="@style/Widget.AppCompat.Button.Borderless.Colored"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:minHeight="48dp"
                    android:background="@mipmap/darkblue" />
            </TableRow>

            <TableRow
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:layout_marginRight="10dp"
                    android:text="标准"
                    android:textColor="@color/black" />
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:layout_marginRight="10dp"
                    android:text="马卡龙"
                    android:textColor="@color/black" />
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:layout_marginRight="10dp"
                    android:text="草木青"
                    android:textColor="@color/black" />
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:text="极夜蓝"
                    android:textColor="@color/black" />
            </TableRow>
        </TableLayout>
    </LinearLayout>
</androidx.cardview.widget.CardView>

4.3 MyBottomSheetDialog.java的实现

创建MyBottomSheetDialog.java,这里终于可以对我们下载好并放在Assets文件夹里的样式文件进行调用啦!

//自定义底部菜单栏样式
public class MyBottomSheetDialog extends BottomSheetDialog {
    

    Context context = null;
    AMap aMap = null;

    public MyBottomSheetDialog(@NonNull Context context, AMap aMap) {
    
        super(context);
        this.context = context;
        this.aMap = aMap;
    }

    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);

        Button btn_standard = (Button) findViewById(R.id.btn_standard);
        Button btn_macaron = (Button) findViewById(R.id.btn_macaron);
        Button btn_grass = (Button) findViewById(R.id.btn_grass);
        Button btn_darkblue = (Button) findViewById(R.id.btn_darkblue);
        Button tv_dialog_cancel = (Button) findViewById(R.id.tv_dialog_cancel);

        btn_standard.setOnClickListener(v -> {
    
            Mapui.setAssetsStyle(aMap,context,style_standard,style_extra_standard);
            this.hide();
        });

        btn_macaron.setOnClickListener(v -> {
    
            Mapui.setAssetsStyle(aMap,context,style_macaron,style_extra_macaron);
            this.hide();
        });

        btn_grass.setOnClickListener(v -> {
    
            Mapui.setAssetsStyle(aMap,context,style_grass,style_extra_grass);
            this.hide();
        });

        btn_darkblue.setOnClickListener(v -> {
    
            Mapui.setAssetsStyle(aMap,context,style_darkblue,style_extra_darkblue);
            this.hide();
        });

        tv_dialog_cancel.setOnClickListener(v -> this.hide());
    }
}

五、Android Studio图标库的使用以及自定义图标

因为该示例中需要用到一些其他图标,于是我就了解了一下Android Studio自带的图标库的使用。而有些图标自带库中也找不到,比如我需要一个地图app的logo,那么我们如何获得该图标并在项目中进行使用呢?

5.1 Android Studio图标库

右键res->new->Image Assets。
在这里插入图片描述
此处只分享该示例使用图标的一些方法,可能不是适合所有项目。因为我需要的基本是圆形图标,就用了Icon Type为launcher Icons的图标。记得修改一下name。如果是使用自带库里的图标,选择Assets Type中的Clip Art。然后会弹出Select Icon的选择框。
还可以调整foreground和background的颜色。
在这里插入图片描述
选好以后点击finish就会生成xxxhdpi, xxhdpi, xhdpi, hdpi, mdpi五种标准的格式,会自动放在这res下的几个文件夹里面。

5.2 自定义图标

如果安卓自带库里没有想要的图标,我们可以在 阿里巴巴矢量图标库 这个网站找到大量免费的图标资源。可以直接搜索需要的图标,比如“地图”。
下载好png格式的图片后,依照5.1的方法打开Image Asset设置,在Asset Type一项中选择Image,然后上传文件path。
可以调整padding和background颜色。
在这里插入图片描述
最后也是生成五种标准的格式。

六、各个类的调用关系

在示例中的java文件有MainActivity(代码在3.3)、MyBottomSheetDialog(代码在4.3)、Mapui(代码在2.2)。
对应的xml文件是activity_main.xml(代码在3.2)、bottom_sheet_dialog_layout.xml(代码在4.2)。

在MainActivity调用了SuspendButtonLayout和MyBottomSheetDialog;
在MyBottomSheetDialog中调用了Mapui。

七、参考博客

Android高德地图实现自定义地图样式

Android悬浮按钮的使用方法

Android tools:replace的使用

BottomSheetDialog 使用详解,设置圆角、固定高度、默认全屏等

Bottom Sheet

还在用android.support?该考虑迁移AndroidX了!

AndroidStudio使用系统自带图标

该示例不提供完整代码,因为本文仅展示了小组项目中我个人完成的部分,其他组员完成的部分我无权分享。如有疑问,可以向我咨询。
非常感谢看到这里的你!
如果对你有帮助的话,欢迎留下点赞和评论~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ycsss/article/details/111934841

智能推荐

艾美捷Epigentek DNA样品的超声能量处理方案-程序员宅基地

文章浏览阅读15次。空化气泡的大小和相应的空化能量可以通过调整完全标度的振幅水平来操纵和数字控制。通过强调超声技术中的更高通量处理和防止样品污染,Epigentek EpiSonic超声仪可以轻松集成到现有的实验室工作流程中,并且特别适合与表观遗传学和下一代应用的兼容性。Epigentek的EpiSonic已成为一种有效的剪切设备,用于在染色质免疫沉淀技术中制备染色质样品,以及用于下一代测序平台的DNA文库制备。该装置的经济性及其多重样品的能力使其成为每个实验室拥有的经济高效的工具,而不仅仅是核心设施。

11、合宙Air模块Luat开发:通过http协议获取天气信息_合宙获取天气-程序员宅基地

文章浏览阅读4.2k次,点赞3次,收藏14次。目录点击这里查看所有博文  本系列博客,理论上适用于合宙的Air202、Air268、Air720x、Air720S以及最近发布的Air720U(我还没拿到样机,应该也能支持)。  先不管支不支持,如果你用的是合宙的模块,那都不妨一试,也许会有意外收获。  我使用的是Air720SL模块,如果在其他模块上不能用,那就是底层core固件暂时还没有支持,这里的代码是没有问题的。例程仅供参考!..._合宙获取天气

EasyMesh和802.11s对比-程序员宅基地

文章浏览阅读7.7k次,点赞2次,收藏41次。1 关于meshMesh的意思是网状物,以前读书的时候,在自动化领域有传感器自组网,zigbee、蓝牙等无线方式实现各个网络节点消息通信,通过各种算法,保证整个网络中所有节点信息能经过多跳最终传递到目的地,用于数据采集。十多年过去了,在无线路由器领域又把这个mesh概念翻炒了一下,各大品牌都推出了mesh路由器,大多数是3个为一组,实现在面积较大的住宅里,增强wifi覆盖范围,智能在多热点之间切换,提升上网体验。因为节点基本上在3个以内,所以mesh的算法不必太复杂,组网形式比较简单。各厂家都自定义了组_802.11s

线程的几种状态_线程状态-程序员宅基地

文章浏览阅读5.2k次,点赞8次,收藏21次。线程的几种状态_线程状态

stack的常见用法详解_stack函数用法-程序员宅基地

文章浏览阅读4.2w次,点赞124次,收藏688次。stack翻译为栈,是STL中实现的一个后进先出的容器。要使用 stack,应先添加头文件include<stack>,并在头文件下面加上“ using namespacestd;"1. stack的定义其定义的写法和其他STL容器相同, typename可以任意基本数据类型或容器:stack<typename> name;2. stack容器内元素的访问..._stack函数用法

2018.11.16javascript课上随笔(DOM)-程序员宅基地

文章浏览阅读71次。<li> <a href = "“#”>-</a></li><li>子节点:文本节点(回车),元素节点,文本节点。不同节点树:  节点(各种类型节点)childNodes:返回子节点的所有子节点的集合,包含任何类型、元素节点(元素类型节点):child。node.getAttribute(at...

随便推点

layui.extend的一点知识 第三方模块base 路径_layui extend-程序员宅基地

文章浏览阅读3.4k次。//config的设置是全局的layui.config({ base: '/res/js/' //假设这是你存放拓展模块的根目录}).extend({ //设定模块别名 mymod: 'mymod' //如果 mymod.js 是在根目录,也可以不用设定别名 ,mod1: 'admin/mod1' //相对于上述 base 目录的子目录}); //你也可以忽略 base 设定的根目录,直接在 extend 指定路径(主要:该功能为 layui 2.2.0 新增)layui.exten_layui extend

5G云计算:5G网络的分层思想_5g分层结构-程序员宅基地

文章浏览阅读3.2k次,点赞6次,收藏13次。分层思想分层思想分层思想-1分层思想-2分层思想-2OSI七层参考模型物理层和数据链路层物理层数据链路层网络层传输层会话层表示层应用层OSI七层模型的分层结构TCP/IP协议族的组成数据封装过程数据解封装过程PDU设备与层的对应关系各层通信分层思想分层思想-1在现实生活种,我们在喝牛奶时,未必了解他的生产过程,我们所接触的或许只是从超时购买牛奶。分层思想-2平时我们在网络时也未必知道数据的传输过程我们的所考虑的就是可以传就可以,不用管他时怎么传输的分层思想-2将复杂的流程分解为几个功能_5g分层结构

基于二值化图像转GCode的单向扫描实现-程序员宅基地

文章浏览阅读191次。在激光雕刻中,单向扫描(Unidirectional Scanning)是一种雕刻技术,其中激光头只在一个方向上移动,而不是来回移动。这种移动方式主要应用于通过激光逐行扫描图像表面的过程。具体而言,单向扫描的过程通常包括以下步骤:横向移动(X轴): 激光头沿X轴方向移动到图像的一侧。纵向移动(Y轴): 激光头沿Y轴方向开始逐行移动,刻蚀图像表面。这一过程是单向的,即在每一行上激光头只在一个方向上移动。返回横向移动: 一旦一行完成,激光头返回到图像的一侧,准备进行下一行的刻蚀。

算法随笔:强连通分量-程序员宅基地

文章浏览阅读577次。强连通:在有向图G中,如果两个点u和v是互相可达的,即从u出发可以到达v,从v出发也可以到达u,则成u和v是强连通的。强连通分量:如果一个有向图G不是强连通图,那么可以把它分成躲个子图,其中每个子图的内部是强连通的,而且这些子图已经扩展到最大,不能与子图外的任一点强连通,成这样的一个“极大连通”子图是G的一个强连通分量(SCC)。强连通分量的一些性质:(1)一个点必须有出度和入度,才会与其他点强连通。(2)把一个SCC从图中挖掉,不影响其他点的强连通性。_强连通分量

Django(2)|templates模板+静态资源目录static_django templates-程序员宅基地

文章浏览阅读3.9k次,点赞5次,收藏18次。在做web开发,要给用户提供一个页面,页面包括静态页面+数据,两者结合起来就是完整的可视化的页面,django的模板系统支持这种功能,首先需要写一个静态页面,然后通过python的模板语法将数据渲染上去。1.创建一个templates目录2.配置。_django templates

linux下的GPU测试软件,Ubuntu等Linux系统显卡性能测试软件 Unigine 3D-程序员宅基地

文章浏览阅读1.7k次。Ubuntu等Linux系统显卡性能测试软件 Unigine 3DUbuntu Intel显卡驱动安装,请参考:ATI和NVIDIA显卡请在软件和更新中的附加驱动中安装。 这里推荐: 运行后,F9就可评分,已测试显卡有K2000 2GB 900+分,GT330m 1GB 340+ 分,GT620 1GB 340+ 分,四代i5核显340+ 分,还有写博客的小盒子100+ 分。relaybot@re...

推荐文章

热门文章

相关标签