博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
导入样机_如何开始构建Android应用程序:创建样机,UI和XML布局
阅读量:2526 次
发布时间:2019-05-11

本文共 38807 字,大约阅读时间需要 129 分钟。

导入样机

Kriptofolio应用程序系列-第2部分 (Kriptofolio app series - Part 2)

So how do you actually start to build a new app? What should be your first move? If you think we just need to launch Android Studio and jump directly to the code, think again. That’s exactly the thing I would advise not to do as it can do more damage than good. But it is so tempting to start writing your first lines of code as soon as possible.

那么,您实际上是如何开始构建新应用的呢? 您的第一步应该是什么? 如果您认为我们只需要启动Android Studio并直接跳转到代码,请三思。 我绝对不建议这样做,因为它可能造成的损害大于好处。 但是诱使您尽快开始编写第一行代码。

Instead I would suggest focusing on making a wise plan with UI mockups. Remember that every good new app project should start with that. With this approach you will not loose a lot of time and will be able to build high quality products from the beginning.

相反,我建议重点关注使用UI原型制定明智的计划。 请记住,每个好的新应用程序项目都应从此开始。 使用这种方法,您将不会浪费很多时间,并且能够从一开始就构建高质量的产品。

So in this part of the series, I will present “Kriptofolio” (previously “My Crypto Coins”) app mockups and discuss how to create them. Also we are going to build all the UI layouts. These layouts will become our solid foundation indicating clearly what to code. Finally we will localize our app to different languages and learn how to handle the ones which are written from right to left.

因此,在本系列的这一部分中,我将介绍“ Kriptofolio”(以前称为“我的加密货币”)应用程序模型,并讨论如何创建它们。 另外,我们将构建所​​有UI布局。 这些布局将成为我们扎实的基础,清楚地表明要编码的内容。 最后,我们将应用程序本地化为不同的语言,并学习如何处理从右到左书写的内容。

系列内容 (Series content)

  • Part 2: How to start building your Android app: creating Mockups, UI, and XML layouts (you’re here)

    第2部分:如何开始构建Android应用:创建样机,UI和XML布局(在此处)

样机 (Mockups)

There are various ways you can create your project mockups. The simplest one is to take a pencil and a sheet of paper and start drawing on it. The best part is this way doesn’t cost you anything and you can start immediately. Oh and I almost forgot, you should also get yourself an eraser as there will not be any undo function. 🙂

您可以通过多种方式创建项目模型。 最简单的方法是拿一支铅笔和一张纸,然后在其上绘图。 最好的部分是这种方式不会花费您任何费用,您可以立即开始。 哦,我差点忘了,您也应该给自己一个橡皮擦,因为它没有任何撤消功能。 🙂

If you, like I, feel that you need more functionality, then consider using special software for creating detailed mockups. I prefer using software instead of pencil & paper, even if it requires you to invest your money to buy it and your time to learn how to use it.

如果像我一样觉得自己需要更多功能,则可以考虑使用特殊软件来创建详细的模型。 我更喜欢使用软件而不是铅笔和纸,即使它需要您花钱购买它并花时间学习如何使用它。

There are various software options on the market to choose from. You will have to do your own investigation into which one best fits all your needs. For all my projects mockups right now I am using Mockups for Desktop app. Balsamiq is rapid, effective and very easy to use wire framing software. As I am rather happy with it, I recommend it for creating Android apps, so please feel free to try.

市场上有多种软件可供选择。 您将需要自己进行调查,以找出最适合您所有需求的方法。 现在,对于我所有的项目样机,我都使用 Mockups for Desktop应用程序。 Balsamiq是快速,有效且非常易于使用的线框图软件。 我对此很满意,因此推荐您创建Android应用,因此请随时尝试。

I started My Crypto Coins app project by creating well thought-out and very detailed mockups. I thought to myself that if I create everything in a very detailed way, than I will avoid mistakes. I will also not waste time for suddenly changing functionality during the development process. If you put a lot of effort in creating good mockups, than, with a little bit of imagination, you can see and feel the final product.

我通过创建经过深思熟虑和非常详细的模型来启动My Crypto Coins应用程序项目。 我心想,如果我以非常详细的方式创建所有内容,那么我将避免错误。 我也不会浪费时间在开发过程中突然更改功能。 如果您花费大量精力来创建好的模型,那么您只需一点点想象力,便可以看到并感受到最终产品。

My goal was to have everything defined in the mockups like it should look in the end product. For that I tried not to rush but to spend as much time as I needed. Here are my final mockups for My Crypto Coins app:

我的目标是在样机中定义所有内容,就像在最终产品中一样。 为此,我尽量不要着急,而要花尽可能多的时间。 这是我的“我的加密货币”应用程序的最终模型:

库存设计—材质 (Stock design — Material)

Another important thing to talk about is the app’s visual design. At the time of this writing, is the stock visual design recommended by Google for all Android apps. And guess what — you can’t go wrong with stock design.

讨论的另一重要事项是应用程序的视觉设计。 在撰写本文时, 是Google为所有Android应用推荐的常规视觉设计。 猜猜是什么-股票设计不会出错。

For My Crypto Coins app we will be using Material Design. The app follows the best practices defined in the detailed online guidelines.

对于“我的加密货币”应用程序,我们将使用“材料设计”。 该应用程序遵循详细的在线指南中定义的最佳做法。

— official material design living specs document which will be our design guidelines for this project.

—正式的材料设计使用规格文档,这将是我们针对该项目的设计指南。

版面 (Layouts)

Now when we already have wireframes of our app prepared, it’s time to build real UI. Again we could jump into writing code, but why rush? Instead I would recommend concentrating on building all your XML layouts. My advice here would be that the more you manage to put into XML the less code you will need to write.

现在,当我们已经准备好应用程序的线框时,该构建真实的UI了。 同样,我们可以跳入编写代码,但是为什么要着急呢? 相反,我建议您专注于构建所有XML布局。 我的建议是,您越努力地将XML放入XML中,您将需要编写的代码就越少。

The Android team constantly improves the way you can build your UI by adding new features to XML layouts. Sometimes it’s so tempting to write few lines of code to reach a desired look. But it’s better to investigate the topic more deeply to find if it is possible to do without code. Remember: less code makes your project look cleaner. It will also be more understandable for other developers and easier to maintain.

Android团队通过向XML布局添加新功能来不断改进构建UI的方式。 有时写几行代码以达到期望的外观非常诱人。 但是最好是更深入地研究该主题,以发现是否可以在没有代码的情况下进行操作。 切记:更少的代码可使您的项目看起来更简洁。 对于其他开发人员来说,它也将更易于理解并且易于维护。

Finally when you create all your XML layouts, you will feel like you have your app made. You will be able to launch it and see how it feels for the end user. It doesn’t matter that it is showing some fake data and does nothing. Now you have the last chance to make some drastic changes.

最后,当您创建所有XML布局时,您会感觉自己已经完成了应用程序。 您将能够启动它,并查看最终用户的感受。 没关系,它显示了一些虚假数据,什么也不做。 现在,您有最后一次机会进行一些大的更改。

If you are building an app for somebody else, it’s such a good time to present it. Maybe you will be asked to make some surprising last minute changes. That way you will avoid writing code for functionality that will never be used. A lot of people don’t have enough imagination and they need to see and touch first to decide if it is what they want. So don’t leave your layouts for the last step in your work process.

如果您要为其他人构建应用程序,那么现在是展示它的好时机。 也许您会被要求在最后一刻做出一些令人惊讶的更改。 这样,您将避免编写永远不会使用的功能代码。 许多人没有足够的想象力,因此他们需要先查看并触摸才能确定这是否是他们想要的。 因此,请勿将布局留在工作流程的最后一步。

For this app I will be using various components that are common in all modern Android apps:

对于这个应用程序,我将使用所有现代Android应用程序中常见的各种组件:

  • — a super-powered FrameLayout, the main appeal of which is its ability to coordinate the animations and transitions of the views within it.

    —超级功能的FrameLayout,其主要吸引力在于它能够协调其中的视图的动画和过渡效果。

  • — a vertical LinearLayout which implements many of the features of material design’s app bar concept, namely scrolling gestures.

    —垂直的LinearLayout,它实现了材质设计的应用程序栏概念的许多功能,即滚动手势。

  • — a generalization of action bars for use within application layouts.

    -用于在应用程序布局中使用的操作的概括。

  • — a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of a AppBarLayout.

    — Toolbar的包装,它实现了折叠的应用程序栏。 它旨在用作AppBarLayout的直接子级。

  • — a ViewGroup which allows you to position and size widgets in a flexible way. Imagine a RelativeLayout on steroids.

    —一个ViewGroup,它允许您灵活地定位和调整窗口小部件的大小。 想象一下在类固醇上的RelativeLayout。

  • — the widget which allows the swipe-to-refresh user interface pattern to be implemented entirely. It detects the vertical swipe, displays a distinctive progress bar, and triggers callback methods in your app.

    —窗口小部件,该窗口小部件可完全实现从滑动到刷新的用户界面模式。 它检测垂直滑动,显示独特的进度条,并触发应用程序中的回调方法。

  • — a circular button that triggers the primary action in your app’s UI.

    —一个圆形按钮,可触发应用程序UI中的主要操作。

For the main screen we will use a combination of all these components to create nice UI/UX. Users can expand and collapse the top part of the layout to find the total value of all their cryptocurrency portfolio. They can check any change in value during the last 24 hours and change selected fiat currency.

对于主屏幕,我们将使用所有这些组件的组合来创建漂亮的UI / UX。 用户可以展开和折叠布局的顶部以找到其所有加密货币投资组合的总价值。 他们可以检查过去24小时内的任何价值变化,并更改所选的法定货币。

Of course there are other components besides these nine. It is very important to master the whole component palette to know which one to use in any particular case. With the mobile trends changing from time to time the palette will expand too.

当然,除了这九个之外,还有其他组件。 掌握整个组件面板以了解在任何特定情况下使用哪个组件都是非常重要的。 随着移动趋势的不时变化,调色板也会扩展。

I am not going to talk about every component, but my advice is to investigate that on your own. For me the best way to understand them is by trying to build XML layouts manually instead of using automatic drag & drop tools in Android Studio.

我不会讨论每个组件,但我的建议是自己调查。 对我来说,理解它们的最好方法是尝试手动构建XML布局,而不是在Android Studio中使用自动拖放工具。

样式,颜色,尺寸,字符串,图标 (Styles, Colors, Dimensions, Strings, Icons)

At first glance, the things mentioned in this section title may appear not to be important ones. However, I ask that you to put in effort when creating them in any app if you want to make it modern and exclusive. Remember this blog posts series is how to build a MODERN Android app! No matter how wrong it is, people will usually judge your app by its looks first, not its functionality.

乍一看,本节标题中提到的内容似乎并不重要。 但是,如果您要使其成为现代且独占的应用程序,我要求您在创建任何应用程序时做出努力。 记住,本博客系列文章是如何构建MODERN Android应用的! 不管问题有多严重,人们通常会首先根据外观而不是功能来判断您的应用。

So here is a perfect chance to earn new users love from the beginning. These are my tips:

因此,这是从一开始就赢得新用户喜爱的绝佳机会。 这些是我的提示:

  • When building your XML layout files, you should recognize where you repeat some common attributes for the views. Move them to be defined as separate XML styles. That way you will have shorter XML layout files. You can control all the app styling aspects from a separate place. Imagine what benefit it will give you. For example, you could allow the user to choose the app skin (bright, dark, etc.).

    构建XML布局文件时,您应该认识到在哪里重复了视图的一些通用属性。 将它们定义为单独的XML样式。 这样,您将拥有较短的XML布局文件。 您可以从一个单独的位置控制所有应用程序样式方面。 想象一下它将为您带来什么好处。 例如,您可以允许用户选择应用程序外观(亮,暗等)。
  • Define all your app colors in a separate file too, and enjoy ability to experiment with the look by changing them immediately. Sometimes the same product can be given new life and engage users again by simply refreshing with new colors. There are quite a few websites that can help you choose nice colors, but my favorite one is , so take a look.

    您也可以在一个单独的文件中定义所有应用颜色,并可以通过立即更改它们来尝试外观。 有时,同一产品可以被赋予新的生命,并通过简单地用新的颜色刷新来再次吸引用户。 有很多网站可以帮助您选择漂亮的颜色,但是我最喜欢的一个是 ,所以请看一下。

  • Define your app dimensions in a separate file. This will allow you to adjust your app to look good on different size screens.

    在单独的文件中定义您的应用尺寸。 这将使您可以调整应用程序,使其在不同尺寸的屏幕上看起来都不错。
  • All your strings should not be hard-coded, and Android Studio will inform you if you forget. Do not ignore that. The best part when your strings are separated is you can translate your app to different languages.

    您的所有字符串都不应进行硬编码,如果您忘记了,Android Studio会通知您。 不要忽略这一点。 字符串分开时最好的部分是可以将您的应用翻译成其他语言。
  • When using icons for your app, always prefer an XML vector drawable format. That’s the new recommended standard and a clever way to go to avoid any pixelation. To find many professionally made material design style icons from the community, please check out . I used this website to get icons for My Crypto Coins app.

    当为您的应用程序使用图标时,始终首选XML矢量可绘制格式。 这是新推荐的标准,也是避免像素化的明智方法。 要从社区中找到许多专业制作的材料设计样式图标,请访问 。 我使用此网站获取“我的加密货币”应用程序的图标。

回收站视图 (RecyclerView)

The main screen of My Crypto Coins app will consist of a list of cryptocurrencies that the user holds. For this purpose the RecyclerView widget is the best fit. It is a widget that displays a scrolling list of elements based on large data sets (or data that frequently changes).

我的加密货币应用程序的主屏幕将包含用户持有的加密货币列表。 为此,最适合使用RecyclerView小部件。 它是一个小部件,可基于大型数据集(或经常更改的数据)显示元素的滚动列表。

Because of its advantages, RecyclerView is the recommended component for creating any list screen. It is a more advanced and flexible version of the simpler ListView component. We will talk about it later too. In this part we are creating just layouts. We are not concentrating on coding.

由于其优点,RecyclerView是创建任何列表屏幕的推荐组件。 它是更简单的ListView组件的更高级,更灵活的版本。 我们稍后也会讨论。 在这一部分中,我们仅创建布局。 我们不专注于编码。

To see our app visually, we will have to implement RecyclerView by writing some code. These are the steps to implement RecyclerView:

为了直观地查看我们的应用程序,我们将必须通过编写一些代码来实现RecyclerView。 这些是实现RecyclerView的步骤:

1.添加一个RecyclerView组件。 (1. Add a RecyclerView component.)

Our MainActivity layout is activity_main.xml. This layout includes content_main.xml layout which is a fragment. This MainActivityListFragment layout inflates fragment_main_list.xml. So you should add RecyclerView component here.

我们的MainActivity布局是activity_main.xml 。 此布局包括一个片段的content_main.xml布局。 此MainActivityListFragment布局会增加fragment_main_list.xml 。 因此,您应该在此处添加RecyclerView组件。

...
...

As you see we configure our RecyclerView to leave some padding space at the bottom. We do this to avoid covering the last list item with the FloatingActionButton. Also we turn on the vertical scrollbar so it’s available.

如您所见,我们将RecyclerView配置为在底部保留一些填充空间。 我们这样做是为了避免用FloatingActionButton覆盖最后一个列表项。 另外,我们打开垂直滚动条,使其可用。

2.创建RecyclerView行布局。 (2. Create RecyclerView row layout.)

For our initial purpose we will only set the item name for each row. Our simplified layout should look like this.

为了我们的最初目的,我们将只为每一行设置项目名称。 我们简化的布局应如下所示。

...
...

3.创建数据适配器类。 (3. Create data adapter class.)

Our adapter for now will accept string data. Later we will need to create a separate class data model. We will need to pass more information than only one string.

现在,我们的适配器将接受字符串数据。 稍后,我们将需要创建一个单独的类数据模型。 我们将需要传递的信息不仅仅是一个字符串。

class MainRecyclerViewAdapter(val dataList: ArrayList
) : RecyclerView.Adapter
() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder { val v = LayoutInflater.from(parent.context).inflate(R.layout.fragment_main_list_item, parent, false) return CustomViewHolder(v) } override fun onBindViewHolder(holder: CustomViewHolder, position: Int) { holder.txtName?.text = dataList[position] } override fun getItemCount(): Int { return dataList.size } inner class CustomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val txtName = itemView.findViewById
(R.id.item_name) }}

4.将RecyclerView连接到自定义适配器。 (4. Connect RecyclerView to custom adapter.)

class MainActivityListFragment : Fragment() {    private lateinit var recyclerView: RecyclerView    private lateinit var recyclerAdapter: MainRecyclerViewAdapter    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,                              savedInstanceState: Bundle?): View? {        val v: View = inflater.inflate(R.layout.fragment_main_list, container, false)        recyclerView = v.findViewById(R.id.recyclerview_fragment_main_list)        return v    }    override fun onActivityCreated(savedInstanceState: Bundle?) {        super.onActivityCreated(savedInstanceState)        setupList()    }    private fun setupList() {        val data = ArrayList
() data.add("Bitcoin") data.add("Etherium") data.add("Ripple") data.add("Bitcoin Cash") data.add("Litecoin") data.add("NEO") data.add("Stellar") data.add("EOS") data.add("Cardano") data.add("Stellar") data.add("IOTA") data.add("Dash") data.add("Monero") data.add("TRON") data.add("NEM") data.add("ICON") data.add("Bitcoin Gold") data.add("Zcash") data.add("Verge") recyclerView.layoutManager = LinearLayoutManager(activity) recyclerAdapter = MainRecyclerViewAdapter(data) recyclerView.adapter = recyclerAdapter }}

Done! Now our main screen looks like this:

做完了! 现在,我们的主屏幕如下所示:

列表显示 (ListView)

In this project, we will use ListView for the screen where you can add crypto coin(s) which you already hold. Because of its shortcomings in recent years it is hardly used anymore.

在这个项目中,我们将使用ListView作为屏幕,您可以在其中添加已经持有的加密硬币。 由于近年来的缺点,几乎不再使用它了。

So I guess a lot of you at this moment are wondering why I decided to use it in My Crypto Coins app when we could create the same functionality easily with RecyclerView.

因此,我想现在很多人都想知道为什么我决定在My Crypto Coins应用程序中使用它时,才能使用RecyclerView轻松创建相同的功能。

Remember, though, that this project was created for training purposes first. I thought it would be beneficial to gain insights into ListView and how it works. Any developer may run into ListView in legacy code, and it’s best to know how to work with it. Besides, the list we will be creating is so simple that ListView’s technical limitations won’t cause us any problems.

但是请记住,该项目是首先为培训目的而创建的。 我认为深入了解ListView及其工作方式将是有益的。 任何开发人员都可能会在遗留代码中遇到ListView,最好知道如何使用它。 此外,我们将要创建的列表非常简单,以至于ListView的技术限制不会给我们带来任何问题。

Let’s follow the very similar steps needed to implement ListView:

让我们遵循实现ListView所需的非常相似的步骤:

1.添加一个ListView组件。 (1. Add a ListView component.)

The first thing to do is to add a ListView to AddSearchActivity. Open the activity layout file activity_add_search.xml and you will see that it includes content_add_search.xml. There we will add the ListView component.

首先要做的是将ListView添加到AddSearchActivity 。 打开活动布局文件activity_add_search.xml ,您将看到它包含content_add_search.xml 。 在那里,我们将添加ListView组件。

...
...

2.创建ListView行布局。 (2. Create ListView row layout.)

As before, just for initial purposes, we will only set the item name for each row. Here is the simplified layout:

和以前一样,仅出于初始目的,我们将仅为每一行设置项目名称。 这是简化的布局:

...
...

3.创建数据适配器类。 (3. Create data adapter class.)

Like RecyclerView our ListView adapter for now will accept only string data to get the item name and show it on screen. Later we will use a separate class data model. As for this part, we want to build a very simple list displaying only cryptocurrency titles. Instead of creating our custom adapter we could use the default, ArrayAdapter.

像RecyclerView一样,我们的ListView适配器现在将仅接受字符串数据以获取项目名称并在屏幕上显示。 稍后,我们将使用单独的类数据模型。 对于这一部分,我们希望构建一个非常简单的列表,仅显示加密货币标题。 代替创建我们的自定义适配器,我们可以使用默认的ArrayAdapter。

class AddSearchListAdapter(context: Context, private val dataSource: ArrayList
) : BaseAdapter() { private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val view: View val holder: CustomViewHolder if (convertView == null) { view = inflater.inflate(R.layout.activity_add_search_list_item, parent, false) holder = CustomViewHolder() holder.nameTextView = view.findViewById(R.id.item_name) view.tag = holder } else { view = convertView holder = convertView.tag as CustomViewHolder } val nameTextView = holder.nameTextView nameTextView.text = getItem(position) as String return view } override fun getItem(position: Int): Any { return dataSource[position] } override fun getItemId(position: Int): Long { return position.toLong(); } override fun getCount(): Int { return dataSource.size } inner class CustomViewHolder { lateinit var nameTextView: AppCompatTextView }}

As you see in the adapter code, by creating CustomViewHolder object I use the ViewHolder pattern. It stores list row view references. Calling the findViewById() method only occurs a couple of times. It allows us to make our list scrolling act smoothly and efficiently.

如您在适配器代码中看到的,通过创建CustomViewHolder对象,我使用了ViewHolder模式。 它存储列表行视图引用。 调用findViewById()方法仅发生两次。 它使我们能够使列表滚动平稳有效地进行。

The ListView doesn’t require us to use the ViewHolder pattern. The RecyclerView’s adapter gives us that kind of protection by default, as it forces us to use it.

ListView不需要我们使用ViewHolder模式。 RecyclerView的适配器默认情况下会为我们提供这种保护,因为它迫使我们使用它。

4.将ListView连接到自定义适配器。 (4. Connect ListView to custom adapter.)

With default ArrayAdapter it could look like val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, data). That’s the beauty of the ListView component. If you want, you can create a simple list really fast without building your own adapter or row layout (skip steps 2 and 3).

使用默认的ArrayAdapter可能看起来像val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, data) 。 那就是ListView组件的美。 如果需要,您可以快速创建一个简单的列表,而无需构建自己的适配器或行布局(跳过步骤2和3)。

class AddSearchActivity : AppCompatActivity() {    private lateinit var listView: ListView    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_add_search)        setSupportActionBar(toolbar2)        supportActionBar?.setDisplayHomeAsUpEnabled(true)        val data = ArrayList
() data.add("Bitcoin") data.add("Etherium") data.add("Ripple") data.add("Bitcoin Cash") data.add("Litecoin") data.add("NEO") data.add("Stellar") data.add("EOS") data.add("Cardano") data.add("Stellar") data.add("IOTA") data.add("Dash") data.add("Monero") data.add("TRON") data.add("NEM") data.add("ICON") data.add("Bitcoin Gold") data.add("Zcash") data.add("Verge") val adapter = AddSearchListAdapter(this, data) listView = findViewById(R.id.listview_activity_add_search) listView.adapter = adapter } ...}

ListView setup is ready!

ListView设置已准备就绪!

搜索视图 (SearchView)

In the same screen with all cryptocurrencies listed, we also need to add SearchView. Search will be a useful functionality to have for any user who wants to find a specific cryptocurrency by typing its name. For this part we will not build functionality fully but just implement its visual part. Follow these steps to add SearchView to the project:

在列出所有加密货币的同一屏幕上,我们还需要添加SearchView。 搜索将是想要通过键入其名称来查找特定加密货币的任何用户的有用功能。 对于这一部分,我们不会完全构建功能,而只是实现其可视部分。 请按照以下步骤将SearchView添加到项目中:

1.声明XML中的可搜索配置。 (1. Declare the searchable configuration in XML.)

The searchable configuration file should be added in your res directory named xml. Here you can specify attributes for your SearchView component which define how it behaves.

可搜索的配置文件应添加到名为xml的res目录中。 在这里,您可以为SearchView组件指定属性,以定义其行为。

2.创建新活动,它将成为我们的可搜索活动。 (2. Create new activity which will become our searchable activity.)

We are going to create new blank activity which extends AppCompatActivity(). We will name it AddSearchActivity.

我们将创建扩展AppCompatActivity()新空白活动。 我们将其命名为AddSearchActivity

3.在Android清单文件中将新创建的活动指定为可搜索。 (3. Specify newly created activity in Android manifest file to be searchable.)

...
...

We will let the Android system handle the search process. That’s why we add the intent action search and meta-data in the activity element of the AddSearchActivity. The meta-data has name and resource which is linked to the searchable configuration file located in the res/xml folder.

我们将让Android系统处理搜索过程。 这就是为什么我们在AddSearchActivity的activity元素中添加意图操作搜索和元数据的AddSearchActivity 。 元数据具有名称和资源,这些名称和资源链接到位于res / xml文件夹中的可搜索配置文件。

4.创建搜索菜单。 (4. Create search menu.)

Inside the res/menu folder we are going to create a menu resource file.

在res / menu文件夹内,我们将创建一个菜单资源文件。

5.将搜索菜单添加到活动中。 (5. Add search menu to activity.)

We will add the Android search widget as a menu action view.

我们将添加Android搜索小部件作为菜单操作视图。

class AddSearchActivity : AppCompatActivity() {    ...    override fun onCreateOptionsMenu(menu: Menu?): Boolean {        menuInflater.inflate(R.menu.menu_search, menu)        val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager        val searchView = menu?.findItem(R.id.search)?.actionView as SearchView        searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName))        searchView.maxWidth = Integer.MAX_VALUE        return true    }}

Now the SearchView is added to the activity. Still the search functionality is not working. But we have it implemented as we wanted for this part.

现在,SearchView已添加到活动中。 搜索功能仍然无法正常工作。 但是我们已经按照我们希望的这一部分实施了它。

设定值 (Settings)

If you want to create a modern Android app, I recommend that you include a settings screen and give access to app settings for the user. Including settings in your app gives your users the power to control some of the functionality of your app which makes them happier. They are now in control of how the app behaves. So we are going to create a settings screen for My Crypto Coins app too.

如果要创建现代的Android应用程序,建议您包含一个设置屏幕,并为用户提供对应用程序设置的访问权限。 在您的应用程序中包含设置可让您的用户控制您的应用程序的某些功能,从而使他们更快乐。 现在,他们可以控制应用程序的行为方式。 因此,我们也将为“我的加密货币”应用程序创建一个设置屏幕。

You can create a settings screen with Android Studio template and it will generate all the code you need. By default at the time of writing this blog post, settings activity is generated with preference headers. That’s not what we want for such a small app where we plan to have only few settings at first.

您可以使用Android Studio模板创建一个设置屏幕,它将生成您所需的所有代码。 默认情况下,在撰写此博客文章时,将使用首选项标题生成设置活动。 对于这么小的应用程序,我们并不是想要的,因为我们计划一开始只设置很少的设置。

Therefore we are going to build everything manually. Settings screen is designed with an XML-like layout. Let’s go step by step to create again only the visual part for this blog post:

因此,我们将手动构建所有内容。 设置屏幕采用类似XML的布局设计。 让我们一步一步地再次创建仅此博客文章的可视部分:

1.创建首选项屏幕XML文件。 (1. Create preferences screen XML file.)

We are going to create the preferences screen XML file which should be placed in the res/xml directory.

我们将创建首选项屏幕XML文件,该文件应放在res / xml目录中。

2.创建首选项片段。 (2. Create preferences fragment.)

Then we should create a simple blank fragment — SettingsFragment, which should extend PreferenceFragment(). This fragment will create preferences from the XML resource that we created. In the future this fragment will contain all the necessary methods to inflate the XML settings. It will also provide callbacks when the settings are changed.

然后,我们应该创建一个简单的空白片段– SettingsFragment ,该片段应该扩展PreferenceFragment() 。 该片段将从我们创建的XML资源创建首选项。 将来,此片段将包含所有必要的方法以扩充XML设置。 更改设置后,它还将提供回调。

class SettingsFragment : PreferenceFragment() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        addPreferencesFromResource(R.xml.pref_main);    }}

3.创建首选项活动。 (3. Create preferences activity.)

With the settings fragment ready let’s create new activity — AppCompatPreferenceActivity, which extends PreferenceActivity(). This class provides compatibility across all the devices and versions.

准备好设置片段后,让我们创建新的活动AppCompatPreferenceActivity ,它扩展了PreferenceActivity() 。 此类提供了所有设备和版本之间的兼容性。

abstract class AppCompatPreferenceActivity : PreferenceActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        delegate.installViewFactory()        delegate.onCreate(savedInstanceState)        super.onCreate(savedInstanceState)    }    override fun onPostCreate(savedInstanceState: Bundle?) {        super.onPostCreate(savedInstanceState)        delegate.onPostCreate(savedInstanceState)    }    val supportActionBar: ActionBar?        get() = delegate.supportActionBar    fun setSupportActionBar(toolbar: Toolbar?) {        delegate.setSupportActionBar(toolbar)    }    override fun getMenuInflater(): MenuInflater {        return delegate.menuInflater    }    override fun setContentView(@LayoutRes layoutResID: Int) {        delegate.setContentView(layoutResID)    }    override fun setContentView(view: View) {        delegate.setContentView(view)    }    override fun setContentView(view: View, params: ViewGroup.LayoutParams) {        delegate.setContentView(view, params)    }    override fun addContentView(view: View, params: ViewGroup.LayoutParams) {        delegate.addContentView(view, params)    }    override fun onPostResume() {        super.onPostResume()        delegate.onPostResume()    }    override fun onTitleChanged(title: CharSequence, color: Int) {        super.onTitleChanged(title, color)        delegate.setTitle(title)    }    override fun onConfigurationChanged(newConfig: Configuration) {        super.onConfigurationChanged(newConfig)        delegate.onConfigurationChanged(newConfig)    }    override fun onStop() {        super.onStop()        delegate.onStop()    }    override fun onDestroy() {        super.onDestroy()        delegate.onDestroy()    }    override fun invalidateOptionsMenu() {        delegate.invalidateOptionsMenu()    }    private val delegate: AppCompatDelegate by lazy {        AppCompatDelegate.create(this, null)    }}

4.创建设置活动。 (4. Create settings activity.)

class SettingsActivity : AppCompatPreferenceActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setupActionBar()        fragmentManager.beginTransaction().replace(android.R.id.content, SettingsFragment()).commit()    }    private fun setupActionBar() {        supportActionBar?.setDisplayHomeAsUpEnabled(true)    }    override fun onMenuItemSelected(featureId: Int, item: MenuItem): Boolean {        val id = item.itemId        if (id == android.R.id.home) {            if (!super.onMenuItemSelected(featureId, item)) {                NavUtils.navigateUpFromSameTask(this)            }            return true        }        return super.onMenuItemSelected(featureId, item)    }}

5.将设置项添加到主菜单。 (5. Add settings item to main menu.)

6.从溢出菜单中选择设置后,启动新创建的设置活动。 (6. Launch newly created settings activity when the settings is selected from overflow menu.)

class MainActivity : AppCompatActivity() {    ...    override fun onCreateOptionsMenu(menu: Menu): Boolean {        // Inflate the menu; this adds items to the action bar if it is present.        menuInflater.inflate(R.menu.menu_main, menu)        return true    }    override fun onOptionsItemSelected(item: MenuItem): Boolean {        return when (item.itemId) {            R.id.action_settings -> {                startActivity(Intent(this@MainActivity, SettingsActivity::class.java));                return true            }            else -> super.onOptionsItemSelected(item)        }    }}

7.在Android清单文件中指定新创建的设置活动。 (7. Specify newly created settings activity in Android manifest file.)

...

Congratulations, you can finally launch the settings from the toolbar’s menu item.

恭喜,您最终可以从工具栏的菜单项启动设置。

使用第三方聚会库-Gmail样式的翻转圆圈按钮视图 (Using 3rd party libraries — Gmail style flip circle button-view)

OK, there are various opinions about using 3rd party libraries — code created by a developer other than the original vendor of the development platform. Some people avoid them as it is never clear how long and how well they will be supported. Meanwhile others use them as they can accelerate the development process.

好的,关于使用第三方库的观点多种多样,它们是由开发人员而非开发平台的原始供应商创建的代码。 有些人避免使用它们,因为目前尚不清楚他们将得到多长时间和多长时间的支持。 同时其他人使用它们,因为它们可以加快开发过程。

Your decision to use them should depend on your particular case. You should do your own investigation of the library and determine if it flexible enough to fit all your requirements.

您决定使用它们的方法应取决于您的具体情况。 您应该对库进行自己的调查,并确定它是否足够灵活以满足您的所有要求。

For My Crypto Coins app, there is a situation where I would like to create a circle image view. This image should show a specific cryptocurrency icon inside a circle shape. But if the icon doesn’t exist, then I would like to show the first three letters of the cryptocurrency code.

对于“我的加密货币”应用程序,有些情况下我想创建一个圆形图像视图。 该图像应在圆圈内显示特定的加密货币图标。 但是,如果该图标不存在,那么我想显示加密货币代码的前三个字母。

Besides all that I would like to be able to select images by clicking them. Selection should be presented as a short flip view animation.

除了所有我想能够通过单击它们选择图像。 选择内容应以简短的动画形式呈现。

All this UX that I described was not originally invented by me. You can find similar behavior on the Gmail app and it looks really good.

我描述的所有这些UX并不是我最初发明的。 您可以在Gmail应用程序上找到类似的行为,而且看起来确实不错。

But how do we create it? In fact, circle image view is not even a default component which you can find in the Android Studio components palette.

但是我们如何创建它呢? 实际上,圆形图像视图甚至不是您可以在Android Studio组件面板中找到的默认组件。

You could go the hard way and try to create everything yourself, but this could waste time and energy. Instead, you could choose to implement one of the many open source libraries created particularly for that.

您可以努力尝试并尝试自己创建所有内容,但这会浪费时间和精力。 相反,您可以选择实现为此专门创建的众多开源库之一。

For my UI/UX requirement, I found a library on GitHub . After some investigation I decided that it was really professionally made. It is easy to implement and supported long enough to give it a try. So to start using it, we’ll follow these easy steps:

对于我的UI / UX要求,我在GitHub 上找到了一个库。 经过一番调查,我认为它确实是专业制造的。 它很容易实现,并且支持时间足够长,可以尝试一下。 因此,要开始使用它,我们将遵循以下简单步骤:

1.添加依赖项。 (1. Add dependency.)

Import the library into your project.

将库导入到您的项目中。

dependencies {  implementation 'eu.davidea:flipview:1.1.3'}

2.使用它。 (2. Use it.)

Configure FlipView with Android’s usual and custom app attributes. Isn’t that easy?

使用Android的常规和自定义应用程序属性配置FlipView。 那不容易吗?

...

So don’t reinvent the wheel. Always consider using some library first to deliver results faster. And if you project becomes messy, it’s not the old libraries to blame but how well you structure your code. If your project is modular enough there won’t be problems. But that’s a separate topic and I am going to talk about project architecture in later blog posts.

因此,不要重新发明轮子。 始终考虑先使用某些库以更快地交付结果。 而且,如果您的项目变得混乱,那就不是应该责怪的旧库,而是代码结构的良好程度。 如果您的项目足够模块化,那就不会有问题。 但这是一个单独的主题,我将在以后的博客文章中讨论项目架构。

支持RTL的本地化 (Localization with RTL support)

When I decided to create this app, I set myself a goal not only to create it with a default English UI, but also to translate it to my mother tongue, Lithuanian, from the start of development.

当我决定创建此应用程序时,我为自己设定了一个目标,即不仅要使用默认的英语UI来创建它,而且还要从开发开始就将其翻译成我的母语立陶宛语。

This goal lead me to learn about localization in Android. What I have found is that to add support for multiple languages is very easy. As I mentioned before, first you need to separate all your strings to the strings.xml file. Then you can launch the Translations Editor tool inside Android Studio. This will allow you to add new languages support.

这个目标使我学习了Android中的本地化。 我发现,添加对多种语言的支持非常容易。 如前所述,首先您需要将所有字符串都分离到strings.xml文件中。 然后,您可以在Android Studio中启动“翻译编辑器”工具。 这将允许您添加新的语言支持。

You will see that the interface is very intuitive. Now you need to translate each string from your strings.xml file to a new language. A new file will be generated by the IDE in separate directory. For example, for Lithuanian language, it’s values-lt/strings.xml. That’s it! 🙂

您将看到该界面非常直观。 现在,您需要将您的strings.xml文件中的每个字符串转换为一种新的语言。 IDE将在单独的目录中生成一个新文件。 例如,对于立陶宛语,其values-lt/strings.xml 。 而已! 🙂

If you switch your Android device system language to the one you just translated to and then run your app, all the UI will be automatically updated to your translations. Moreover, for My Crypto Coins app, later I plan to add the ability to switch languages at run-time. That’s why you will notice the language switcher inside the settings screen.

如果您将Android设备系统语言切换为刚翻译成的语言,然后运行您的应用,则所有用户界面都会自动更新为您的翻译。 此外,对于“我的加密货币”应用程序,以后我计划添加在运行时切换语言的功能。 因此,您会在设置屏幕中看到语言切换器。

Translating your app to different languages will definitely widen your audience. Why not go further by adding support for a few special languages that are written from Right to Left (RTL) — like Arabic, Hebrew or Persian.

将您的应用翻译成其他语言肯定会扩大您的受众范围。 为什么不增加对从右到左(RTL)编写的几种特殊语言的支持,例如阿拉伯语,希伯来语或波斯语。

Actually to add RTL support is not difficult at all. Just add the support attribute to your manifest file:

实际上,添加RTL支持并不困难。 只需将support属性添加到清单文件中:

...

Congratulations, your app now supports RTL. However you can’t trust blindly that everything will work correctly straightaway. You should check how well it is supported yourself. To do that select one of the RTL languages as your primary device language.

恭喜,您的应用程序现在支持RTL。 但是,您不能盲目地相信一切都会立即正常运行。 您应该检查一下自己对它的支持程度。 为此,请选择一种RTL语言作为主要设备语言。

A few tips for RTL:

RTL的一些技巧:

  • In all your layouts you will need to replace all Left and Right layout properties with Start and End equivalent. For example android:paddingLeft should be replaced with android:paddingStart.

    在所有布局中,您将需要用“ Start和“ End等效项替换所有“ Left和“ Right布局属性。 例如, android:paddingLeft应该替换为android:paddingStart

  • If you don’t have a special drawable for RTL, perhaps you would like to mirror your current ones with a special autoMirrored attribute.

    如果您没有RTL的特殊可绘制对象,则可能希望使用特殊的autoMirrored属性来镜像当前autoMirrored

  • If there are certain places where you need to have LTR instead of RTL, you can do that too. For example to force any layout to LTR just add android:layoutDirection="ltr" to that view. If you need to force text direction inside text view than use android:textDirection="ltr".

    如果在某些地方需要LTR而不是RTL,也可以这样做。 例如,要强制将任何布局设置为LTR,只需将android:layoutDirection="ltr"到该视图。 如果您需要在文本视图内强制使用文本方向,请使用android:textDirection="ltr"

By the way, when using Translations Editor, there is a very useful feature to order a professional translation service. Even if I personally don’t know anything about the Hebrew language, I still set myself a goal to add support for it as an example RTL language for My Crypto Coins project. So this feature seemed like a really good idea to try. I ordered the translation successfully from English to Hebrew directly from the IDE with just a few clicks.

顺便说一句,使用“翻译编辑器”时,有一项非常有用的功能可以订购专业的翻译服务。 即使我个人对希伯来语一无所知,我仍然为自己设定了一个目标,即增加对它的支持,作为“我的加密货币”项目的示例RTL语言。 因此,尝试使用此功能似乎是一个不错的主意。 只需单击几下,我就可以直接从IDE中成功地将英语成功翻译为希伯来语。

最后的想法 (Final thoughts)

In this second part of the series, we created all the UI layouts with some initial code based on detailed mockups. I did not want to go into too much detail on each topic so as not to confuse you. My goal was to show you how to see a bigger picture, how to focus on small details first, and avoid costly mistakes later.

在本系列的第二部分中,我们基于详细的模型使用一些初始代码创建了所有UI布局。 我不想在每个主题上介绍太多细节,以免使您感到困惑。 我的目标是向您展示如何看到更大的图景,如何首先专注于小细节以及如何避免代价高昂的错误。

If you find something not covered well enough, use it as a jumping off point to do your own research. There are always plenty of good resources around the web to learn from. 😉

如果您发现某些东西覆盖得不够好,可以用它作为起点进行自己的研究。 网上总是有很多好的资源可供学习。 😉

资料库 (Repository)

You can find all the XML layouts and code created for this part here:

您可以在此处找到为此部分创建的所有XML布局和代码:

()



Ačiū! Thanks for reading! I originally published this post for my personal blog on May 14, 2018.

阿奇! 谢谢阅读! 我最初于2018年5月14日在我的个人博客上发布了这篇文章。

翻译自:

导入样机

转载地址:http://acwzd.baihongyu.com/

你可能感兴趣的文章
dell support
查看>>
转:Maven项目编译后classes文件中没有dao的xml文件以及没有resources中的配置文件的问题解决...
查看>>
MTK android 设置里 "关于手机" 信息参数修改
查看>>
单变量微积分笔记6——线性近似和二阶近似
查看>>
补几天前的读书笔记
查看>>
HDU 1829/POJ 2492 A Bug's Life
查看>>
CKplayer:视频推荐和分享插件设置
查看>>
CentOS系统将UTC时间修改为CST时间
查看>>
redis常见面试题
查看>>
导航控制器的出栈
查看>>
玩转CSS3,嗨翻WEB前端,CSS3伪类元素详解/深入浅出[原创][5+3时代]
查看>>
iOS 9音频应用播放音频之播放控制暂停停止前进后退的设置
查看>>
Delphi消息小记
查看>>
JVM介绍
查看>>
将PHP数组输出为HTML表格
查看>>
经典排序算法回顾:选择排序,快速排序
查看>>
BZOJ2213 [Poi2011]Difference 【乱搞】
查看>>
一道关于员工与部门查询的SQL笔试题
查看>>
Canvas基础
查看>>
[Hive - LanguageManual] Alter Table/Partition/Column
查看>>