热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

四、融入多媒体元素

四、融入多媒体元素本章将讨论如何在一个项目中加入多媒体元素,并在一个应用中处理多个屏幕。将向读者

四、融入多媒体元素

本章将讨论如何在一个项目中加入多媒体元素,并在一个应用中处理多个屏幕。将向读者展示如何在项目中添加图像、声音和网页。我们将借助一个名为SimpleNumb3r5的项目讨论以下主题:


  • 形成布局

  • 添加图像资源

  • 插入图像视图

  • 插入图像按钮

  • 图像按钮和处理事件

  • 添加音频和多屏幕支持

  • 在网页视图中插入 HTML

  • 使用意图和活动

  • 在清单文件中添加新活动

  • 最终产品——运行、部署和测试应用

对于这一章,我们需要一个新的项目,该项目将涵盖从 2.1 版(应用编程接口级别 7)到最新版本的安卓设备。所以设置android:minSdkVersion为 7,android:targetSdkVersion为 16。

图标和其他资源可以在可下载的源代码中获得(参考本书前言中提到的下载提示)。在开发此应用之前,请下载这些材质。我们不想做平面设计让你的生活变得痛苦。

新 app 选择的名称为 SimpleNumb3r5,如下图截图所示。如果你想知道我们为什么选择安卓 2.1,这是为了扩大设备覆盖范围:

Incorporating Multimedia Elements

创建一个名为 SimpleNumb3r5 的新安卓项目

我们在资源素材中提供启动器图标,在图像文件字段中提供名为ic_launcher-web.png的图像,如下图截图所示。这是这个应用的专用标志。如果你喜欢不同的标志来适合你的应用,欢迎你亲自设计。通过使用该向导,图标启动器将准备好适合各自可绘制文件夹中的xhdpihdpimdpildpi格式。

Incorporating Multimedia Elements

创建启动器图标

下一个屏幕如下图所示,是提供应用的名称。这可以是任何具有适合该应用的正确含义的字符串。布局名称将自动为您创建,并可根据您的喜好进行更改。选择导航类型为,因为它与我们的应用开发无关。

Incorporating Multimedia Elements

选择空白活动

以下截图是正在开发的应用的实体模型。我们有一个屏幕的主要部分,专门显示数字 0 到 9 的图像和拼写。屏幕的底部一行是导航栏,用户可以在其中导航到上一个和下一个屏幕。带扬声器的按钮是让用户听对他们说的数字。小写的 i 按钮是显示信息屏幕的图标。


  • 项目标题(默认情况下显示)。

  • 图像编号位置。该行由合并在一起的三个单元格组成。

  • 底部一行由“上一个”、“信息”、“播放声音”和“下一个”按钮组成。

Incorporating Multimedia Elements

主屏幕模型

添加表格布局

我们的项目将由一个表格布局组成,其中有两个表格行。默认情况下,添加表格布局时,集成开发环境将包括四组表格行。通过使用 XML 代码编辑器删除两行,之前的 app 实体模型可以提供一些指南来删除不使用的行。调整 TableLayout,使其利用屏幕布局的所有空间,如下图截图所示:

Adding a TableLayout

插入表格布局

添加图像资源

通过 Windows 文件管理器将第四章补充文件中提供的图片复制到res/drawable-hdpi文件夹,如下图截图所示。在本练习中,我们只提供hdpi可绘制的图像资源。为xhdpimdpildpi准备所有合适的资源总是一个好的做法。别忘了安卓设备中有很多不同的屏幕尺寸。目前,我们也不考虑平板电脑设备的资源。

Adding the image resources

可提取的资源

然后转到您的项目浏览器(在 Eclipse 中),右键单击res/drawable-hdpi,然后单击刷新。以下截图显示了复制图像资源后drawable-hdpi文件夹的外观:

Adding the image resources

可提取的资源

添加图像视图

如上一张截图所示,我们的应用有一个图像 0 填充了整个屏幕,为了实现这一点,让我们在 TableLayout 的第一行添加一个 ImageView。使用可绘制文件夹中的 no0 图像作为初始图像(零是要显示的第一个数字)。调整图像视图的宽度和高度以填充屏幕。

Adding ImageView

将图像视图添加到应用屏幕

平均分配权重(指定布局中要分配给视图的额外空间),使小部件居中。使用下面截图中显示的按钮将 ImageView 调整到屏幕中心。在图像视图处于活动状态(选中)时执行此操作:

Adding ImageView

均匀分配重量

添加图像按钮

TableLayout 中的第二行是导航按钮(上一个和下一个)和播放声音按钮的。ImageButton 对这类应用更有吸引力。创建图像按钮时,会要求您选择图像。对于第一个按钮,使用图纸上的图像 prev 。第二个是,最后一个是下一个。这些按钮需要一次添加一个,如下图所示:

Adding ImageButtons

添加图像按钮

激活(选择)其中一个按钮,均匀分布,如下图截图所示。这是为了确保所有按钮在屏幕宽度上均匀分布。

Adding ImageButtons

平均分配图像按钮的重量

如果你愿意,可以改变屏幕的背景。已经为您准备了背景图像;它在图纸中被命名为 bglight 。点击应用屏幕上的应用标题/标志,激活主布局。通过单击属性右侧的三点按钮来更改背景属性。稍后,您可以添加 btninfo 按钮来显示该应用的信息。

分配部件的标识

基本上有一个图像视图和三个图像按钮。要更改图像视图标识,请选择它并转到右侧的小部件属性。点击身份证属性上的三点按钮。将图像视图的标识改为图像号,如下图所示:

Assigning the widget's ID

通过属性窗口更改小部件的标识

之后,将所有按钮的所有标识改为BTN 先前的btninfoBTN soudbtnnext 。使用下表作为指南:

|

小部件

|

身份证明

|
| --- | --- |
| image view〔t0〕 | 图像号 |
| 最左侧按钮 | btnprevious |
| 显示应用信息 | btninfo |
| 播放声音按钮 | bonsound |
| 最右侧按钮 | btnnext |

最后,您将看到屏幕,如下所示:

Assigning the widget's ID

主要活动的整体布局设计

以下 XML 代码可通过图形布局选项卡中的activity_simple_numb3rs.xml选项卡中的 XML 编辑器获得:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bglight" >
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
<TableRow
android:id="@+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" >
<ImageView
android:id="@+id/imagenumber"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/no0" />
TableRow>
<TableRow
android:id="@+id/tableRow2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" >
<ImageButton
android:id="@+id/btnprevious"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/prev" />
<ImageButton
android:id="@+id/btninfo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/info" />
<ImageButton
android:id="@+id/btnsound"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/sound" />
<ImageButton
android:id="@+id/btnnext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/next" />
TableRow>
TableLayout>
RelativeLayout>


图像按钮和事件处理

这是我们对图像按钮点击事件进行编码的地方。从src/net.kerul.simplenumb3r5/SimpleNumb3r5.java打开 Java 源代码。在这里,我们将讨论主活动类,它将为屏幕导航提供以下代码:

public class SimpleNumb3r5 extends Activity implements OnClickListener

主类和往常一样,将继承Activity类,并实现OnClickListener来启用小部件交互。

主要变量声明如下:

//initialize all widgets
private ImageView imagenumber;
private ImageButton btnprevious, btninfo, btnsound, btnnext;
//define variables to track screen number, start from 0
private int screennumber=0;
//define a sound controller
private MediaPlayer mp;
//define an array for the sound files
private String[] soundfile={"0.mp3","1.mp3","2.mp3","3.mp3",
"4.mp3","5.mp3","6.mp3","7.mp3","8.mp3","9.mp3"};

Widget 对象是imagenumber至于显示图片数量的容器,我们有btnpreviousbtnsound,按钮有btnnext

screennumber是记录当前屏幕位置的变量;最初给它的值是 0,因为我们有一个从零(0)开始的数字列表。

声控器对象名为mp,字符串数组名为soundfile是从零到九的所有语音数字的录音列表。

onCreate方法是视图中所有小部件初始化并链接在一起的地方,如下所示:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_numb3r5);
imagenumber=(ImageView)findViewById(R.id.imagenumber);
//create the object for the button
btnprevious=(ImageButton)findViewById(R.id.btnprevious);
//this button will initially be disabled
btnprevious.setEnabled(false);
//add listener to the button
btnprevious.setOnClickListener(this);
btninfo=(ImageButton)findViewById(R.id. btninfo);
btninfo.setOnClickListener(this);
btnsound=(ImageButton)findViewById(R.id.btnsound);
btnsound.setOnClickListener(this);
btnnext=(ImageButton)findViewById(R.id.btnnext);
btnnext.setOnClickListener(this);
}//end onCreate

接下来,我们有onClick方法来处理导航交互。我们在这里做的基本上是如果screennumber为 0,禁用btnprevious按钮,如果screennumber大于 0,启用按钮。如果screennumber值为 9,当小于 9 时,btnnext也将被禁用。这些是为了防止当用户试图访问小于 0 或大于 9 的内容时出现运行时错误。btnsound值当前被忽略;稍后当我们处理声音(即声音/音频的播放)时将会讨论它。

//this method is to handle button click
public void onClick(View arg0) {
//when btnprevious is clicked
if(arg0.getId()==R.id.btnprevious){
screennumber--;// Decrement 1 to the screennumber
changeNumber(screennumber);
if(screennumber==0){
// Disable previous Button
btnprevious.setEnabled(false);
}else{
// Enable back disabled Button.
btnprevious.setEnabled(true);
}
changeNumber(screennumber);
btnnext.setEnabled(true);
}
//when btnnext is clicked
else if(arg0.getId()==R.id.btnnext){
screennumber++;//add 1 to the screennumber
changeNumber(screennumber);
if(screennumber==9){
Disable no screen available next
btnnext.setEnabled(false);
}else{
/ Only prevoius screen available
btnnext.setEnabled(true);
}
changeNumber(screennumber);
btnprevious.setEnabled(true);
}
//when btnplay is clicked
else if(arg0.getId()==R.id.btnsound){
//playSound - will implement later
}
else if(arg0.getId()==R.id.btninfo){
//display info will implement later
}
}//end onClick

还有一个额外的方法来切换数字的图像。R.id.imagefile是实际可绘制图像资源的表示。由于我们总共有 10 个图像,R.id返回int,所以我们可以如下使用开关盒 10 次:

//this method is to change the number that appears on the screen
// after the navigation button is clicked
// as R.id retuns int so we use switch
private void changeNumber(int screen){
switch (screen){
case 0: imagenumber.setImageResource(R.drawable.no0);
break;
case 1: imagenumber.setImageResource(R.drawable.no1);
break;
case 2: imagenumber.setImageResource(R.drawable.no2);
break;
case 3: imagenumber.setImageResource(R.drawable.no3);
break;
case 4: imagenumber.setImageResource(R.drawable.no4);
break;
case 5: imagenumber.setImageResource(R.drawable.no5);
break;
case 6: imagenumber.setImageResource(R.drawable.no6);
break;
case 7: imagenumber.setImageResource(R.drawable.no7);
break;
case 8: imagenumber.setImageResource(R.drawable.no8);
break;
case 9: imagenumber.setImageResource(R.drawable.no9);
break;
}
}//end changeNumber


添加音频

在做这个练习之前,把所有的声音资源复制到assets文件夹。您可以通过File Manager将所有 mp3 文件复制到assets文件夹,如下图所示:

Adding audio

将 MP3 文件复制到文件夹资源

onClick方法中添加btnsound的代码。添加以下几行,这样当点击btnplay按钮时,它将执行名为playSound()的方法。此方法将接收字符串参数作为要播放的声音文件名的值。

soundfile数组变量是存储 mp3 文件名列表的变量,而screennumber表示屏幕上的当前数字。

//when btnplay is clicked
else if(arg0.getId()==R.id.btnsound){
//call the method playSound
playSound(soundfile[screennumber].toString());
}//end btnsound clicked

下一个重要的方法是playsound方法。这个方法将播放 mp3 声音文件。soundname参数是包含位于安卓项目assets文件夹中的声音文件名的字符串。

public void playSound(String soundName){
Boolean mpPlayingStatus;
try{//try to check MediaPlayer status
mpPlayingStatus=mp.isPlaying();
}
catch (Exception e){
mpPlayingStatus=false;
}
//if the MediaPlayer is playing a sound, stop it to play new voice
if(mp.isPlaying()){
mp.stop(); //stop the sound
mp.release(); //remove sound from the memory
}
else{
try{
mp = new MediaPlayer();
AssetFileDescriptor afd = getAssets().openFd(soundName);
//set the sound source file
FileDescriptor fd = afd.getFileDescriptor();
mp.setDataSource(fd);
mp.prepare(); // prepare for playback
mp.start(); //play the sound
}//try block
catch(IOException e) {
//display the error message in debug
Log.i("Error playing sound: ", e.toString());
}
}
}//end playSound

以下是对所涉及的变量和过程的解释:


  • try…catch block:这是一个异常处理程序,其目的是封装可能抛出异常的代码。在这种情况下,例外情况是在尝试使用MediaPlayer播放声音文件时尝试捕捉任何问题。如果您注意到,catch 块是当某个代码执行导致异常时将执行的语句。

  • mp是从类MediaPlayer实例化的对象。

    • isPlaying():检查MediaPlayer是否在玩,True是否在玩,反之false是否在玩

    • setDataSource():设置要使用的数据源。这种情况下,数据源为FileDescriptor

    • prepare():同步准备播放器播放

    • play():播放声音文件

    • stop():停止当前声音播放

    • release():从记忆中释放声音



  • afd是从类AssetFileDescriptor实例化的变量。

    • getAssets():通过AssetManager应用编程接口从assets文件夹中检索底层资源

    • openFD():打开String参数中指定的文件

    • getFileDescriptor():返回可用于读取文件中数据的FileDescriptor数据源

    • getStartOffSet():返回该资产条目数据开始的字节偏移量

    • getLength():返回该资产条目数据的总字节数




在应用中添加另一个屏幕

这个练习是在SimpleNumb3r5 app 上增加一个信息屏。关于开发者、电子邮件、脸书粉丝页面和其他信息的信息显示在下一个屏幕中。由于屏幕包含许多文本信息,包括一些图片,因此我们在这里使用一个 HTML 页面作为我们的方法:


  1. 现在,创建一个活动类来处理新屏幕。打开src文件夹,右键点击包名(net.kerul.SimpleNumb3r5),选择新建 | 其他...从选项中选择添加新的安卓活动,点击下一步按钮。然后,选择一个空白活动,点击下一步

  2. Set the activity name as Info, as shown in the following screenshot and the wizard will suggest the screen layout as info_activity. Click on the Finish button.

    Adding another screen in the app

    创建名为“信息”的新活动


  3. 将出现一个空白的新屏幕布局。删除HelloWorld文本视图(默认)。在面板上,打开名为Composite的文件夹。


  4. Click and drag the WebView widget. Change the ID of WebView to webinfo. This layout will be saved in the file info_activity.xml.

    Adding another screen in the app

    添加网络视图小部件



在网页视图中添加 HTML

使用您最喜欢的网页编辑器创建一个网页,或者您可以在提供的资源中重用该网页(在assets文件夹中,文件名info.html)。HTML 页面,如下图截图所示,是一个包含 app 信息的简单 HTML 页面。如果你发现 HTML 太简单,一定要添加自己的信息。在本练习中,我们将把 HTML 页面和资源放在assets文件夹中,因此在继续之前,将 HTML 页面的所有相关资料复制到assets文件夹中。

Adding HTML to WebView

info.html 的网页

接下来是编辑src/net.kerul.simplenumb3r5文件夹中Info.java的源代码。将以下代码添加到现有模板中:

package net.kerul.simplenumb3r5;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class Info extends Activity {
private WebView webinfo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_info);
webinfo=(WebView)findViewById(R.id.webinfo);
//provide the URL path pointing to info.html
webinfo.loadUrl("file:///android_asset/info.html");
}
}

让我们了解一下添加到上面模板的代码的第行和第行:


  • setContentView(R.layout.activity_info) : R.layout.activity_info是指之前创建的布局。

  • webinfo.loadUrl("file:///android_asset/info.html"):这是从特定 URL 加载 HTML 页面的方法。指向assets文件夹中的一个 HTML 文件的路径是file:///android_asset/info.html。该路径在真实设备上找不到,但是它提供了对app asset文件的访问。


意图和活动

意图是对要执行的操作的抽象描述。更具体地说,它是一个异步调用,允许应用从其他安卓组件请求功能,例如服务/活动。它可以与startActivity()命令一起使用来发起活动。SimpleNumb3r5.java中的前一个代码是该应用的主要活动(或类)。我们刚刚创建了文件Info.java中的第二个活动(类)。为了让第二个活动出现,它必须使用一个意图开始。

我们已经决定使用按钮btninfo作为触发器来调用第二个活动。再次,打开文件SimpleNumb3r5.java并添加以下行来调用另一个活动。这些线必须添加到btninfo按钮的onClick方法中。请注意,Intent的一个实例被创建为信息。主类可以使用startActivity()方法调用第二类。Info.class论点指的是第二类。

else if(arg0.getId()==R.id.btninfo){
//invoke the Info activity
Intent info = new Intent(this, Info.class);
startActivity(info);
}Adding Activity in Manifest file

为了通过Intent调用第二类,需要修改Manifest.xml文件。但是,您会注意到,这是从第 20 版开始由安卓开发工具包 自动完成的。如果AndroidManifest.xml缺少以下几行,请手动添加:

<activity
android:name=".Info"
android:label="@string/title_activity_info" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>

如果您需要在网络视图中显示来自互联网的网页,您必须通过在标签上方的AndroidManifest.xml中添加以下这一行来声明用户权限:

<uses-permission android:name="android.permission.INTERNET" />


最终产品运行和测试

在我们经历了所有的过程之后,在模拟器中运行该应用,您将看到以下屏幕:

The final product run and test

SimpleNumb3r5 正在运行

总结

在这一章中,我们探索了一种简单的方法来整合几个多媒体元素,如图像、HTML 页面和语音。最新的软件开发工具包比以前的任何版本都更加用户友好。

在下一章中,我们将了解更多关于不同的小部件,如菜单、复选框、单选按钮,以及关于添加首选项屏幕的信息。


推荐阅读
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • Unity3D引擎的体系结构和功能详解
    本文详细介绍了Unity3D引擎的体系结构和功能。Unity3D是一个屡获殊荣的工具,用于创建交互式3D应用程序。它由游戏引擎和编辑器组成,支持C#、Boo和JavaScript脚本编程。该引擎涵盖了声音、图形、物理和网络功能等主题。Unity编辑器具有多语言脚本编辑器和预制装配系统等特点。本文还介绍了Unity的许可证情况。Unity基本功能有限的免费,适用于PC、MAC和Web开发。其他平台或完整的功能集需要购买许可证。 ... [详细]
  • wpf+mvvm代码组织结构及实现方式
    本文介绍了wpf+mvvm代码组织结构的由来和实现方式。作者回顾了自己大学时期接触wpf开发和mvvm模式的经历,认为mvvm模式使得开发更加专注于业务且高效。与此同时,作者指出mvvm模式相较于mvc模式的优势。文章还提到了当没有mvvm时处理数据和UI交互的例子,以及前后端分离和组件化的概念。作者希望能够只关注原始数据结构,将数据交给UI自行改变,从而解放劳动力,避免加班。 ... [详细]
author-avatar
手机用户2702934194
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有