【Android】 android TV 开发

最近要开发一个tv项目,就去官网看了一些资料。自己边看边整理一些个人认为对我目前有帮助的,这里主要是对官网上的一部分信息进行了粘贴复制。有兴趣的小伙伴可以去官网查看 https://developer.android.google.cn/training/tv/,在这里我就不给大家翻译了。

Ⅰ.Get Start with TV apps

In order to make your app successful on TV devices, you must design new layouts that can be easily understood from 10 feet away, and provide navigation that works with just a directional pad and a select button.

Determine media format support

Prerequisites

Declare a TV activity

An application intended to run on TV devices must declare a launcher activity for TV in its manifest. It uses a CATEGORY_LEANBACK_LAUNCHER intent filter to do this. This filter identifies your app as being enabled for TV, and lets Google Play identify it as a TV app. When a user selects your app on their TV home screen, this intent identifies which activity to launch.

<application
  android:banner="@drawable/banner" >
  ...
  <activity
    android:name="com.example.android.MainActivity"
    android:label="@string/app_name" >

    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
  </activity>

  <activity
    android:name="com.example.android.TvActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.Leanback">

    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
    </intent-filter>

  </activity>
</application>

The second activity manifest entry in this example specifies that activity as the one to launch on a TV device.

Caution: If you do not include the CATEGORY_LEANBACK_LAUNCHER intent filter in your app, it is not visible to users running Google Play on TV devices. Also, if your app does not have this filter when you use developer tools to load it onto a TV device, the app does not appear in the TV user interface.

If you are modifying an existing app for use on TV, your app should not use the same activity layout for TV that it does for phones and tablets. Your TV app's user interface (or TV portion of your existing app) should provide a simpler interface for easy navigation using a remote control from a couch.

Declare Leanback support

Declare that your app uses the Leanback user interface required by Android TV. If you are developing an app that runs on mobile (phones, wearables, tablets, etc.) as well as Android TV, set the required attribute value to false. If you set the required attribute value to true, your app will run only on devices that use the Leanback UI.

<manifest>
    <uses-feature android:name="android.software.leanback"
        android:required="false" />
    ...
</manifest>

Declare touchscreen not required

Applications that are intended to run on TV devices do not rely on touch screens for input. To make this clear, your TV app's manifest must declare that the android.hardware.touchscreen feature is not required. This setting identifies your app as being able to work on a TV device, and is required for your app to be considered a TV app in Google Play. The following code example shows how to include this manifest declaration:

<manifest>
    <uses-feature android:name="android.hardware.touchscreen"
              android:required="false" />
    ...
</manifest>

Provide a home screen banner

If an application includes a Leanback launcher intent filter, it must provide a home screen banner image for each localization. The banner is the app launch point that appears on the home screen in the apps and games rows. To add the banner to your app, describe the banner in the manifest as follows:

<application
    ...
    android:banner="@drawable/banner" >
    ...
</application>

Use the android:banner attribute with the <application> tag to supply a default banner for all application activities, or with the <activity> tag to supply a banner for a specific activity.

The banner should be an xhdpi resource with a size of 320 x 180 px. Text must be included in the image. If your app is available in more than one language, you must provide separate versions of the banner with text for each supported language.

Change the launcher color

When a TV app launches, the system displays an animation that resembles an expanding, filled circle. To customize the color of this animation, set the android:colorPrimary attribute of your TV app or activity to a specific color. You should also set two additional transition overlap attributes to true, as shown in the following snippet from a theme resource XML file:

<resources>
    <style ... >
      <item name="android:colorPrimary">@color/primary</item>
      <item name="android:windowAllowReturnTransitionOverlap">true</item>
      <item name="android:windowAllowEnterTransitionOverlap">true</item>
    </style>
</resources>

Add TV support libraries

  • v17 leanback library - Provides user interface widgets for TV apps, particularly for apps that do media playback.
  • v7 recyclerview library - Provides classes for managing the display of long lists in a memory-efficient manner. Several classes in the v17 leanback library depend on the classes in this library.
  • v7 cardview library - Provides user interface widgets for displaying information cards such as media item pictures and descriptions.
    Note: You are not required to use these support libraries for your TV app. However, we strongly recommend using them, particularly for apps that provide a media catalog browsing interface.
    If you decide to use the v17 leanback library for your app, you should note that it is dependent on the v4 support library. Thus, apps that use the leanback support library must include the following support libraries:
  • v4 support library
  • v7 recyclerview support library
  • v17 leanback support library
  • Build TV playback apps - TVs are built to entertain, so Android provides a set of user interface tools and widgets for building TV apps that play videos and music, and let users browse for the content they want.
  • Help users find your content on TV - With all the content choices at users' fingertips, helping them find content they enjoy is almost as important as providing that content. This training discusses how to surface your content on TV devices.

Run TV apps

Run on a real device

1.Use a USB cable to connect your TV device to your development machine. If needed, refer to documentation provided by your device manufacturer.
2.On your TV device, navigate to Settings.
3.In the Device row, select About.
4.Scroll down to Build and select Build several times until you get the message, "You are now a developer!"
5.Return to Settings. In the Preferences row, select Developer options.
6.Select Debugging > USB debugging and select On.
7.Navigate back to the TV home screen.

Run on a virtual device
  1. Start the AVD Manager. For more information, see the AVD Manager help.
  2. In the AVD Manager dialog, click the Device Definitions tab.
  3. Select one of the Android TV device definitions and click Create AVD.
  4. Select the emulator options and click OK to create the AVD.

Ⅱ.Handle TV hardware

TV hardware is substantially different from other Android devices. TVs do not include some of the hardware features found on other Android devices, such as touch screens, cameras, and GPS receivers. TVs are also completely dependent on secondary hardware devices. In order for users to interact with TV apps, they must use a remote control or game pad. When you build an app for TV, you must carefully consider the hardware limitations and requirements of operating on TV hardware.

Declaring hardware requirements for TV

Android apps can declare hardware feature requirements in the app manifest to ensure that they do not get installed on devices that do not provide those features. If you are extending an existing app for use on TV, closely review your app's manifest for any hardware requirement declarations that might prevent it from being installed on a TV device

<uses-feature android:name="android.hardware.touchscreen"
        android:required="false"/>
<uses-feature android:name="android.hardware.faketouch"
        android:required="false"/>
<uses-feature android:name="android.hardware.telephony"
        android:required="false"/>
<uses-feature android:name="android.hardware.camera"
        android:required="false"/>
<uses-feature android:name="android.hardware.nfc"
        android:required="false"/>
<uses-feature android:name="android.hardware.location.gps"
        android:required="false"/>
<uses-feature android:name="android.hardware.microphone"
        android:required="false"/>
<uses-feature android:name="android.hardware.sensor"

**Note:** Some features have subfeatures like *android.hardware.camera.front*, as described in the [Feature reference](https://developer.android.google.cn/guide/topics/manifest/uses-feature-element.html#features-reference). Be sure to mark as *required="false"* any subfeatures also used in your app.
Caution: Declaring a hardware feature as required by setting its value to true prevents your app from being installed on TV devices or appearing in the Android TV home screen launcher.

Pausing playback during low-power mode

Some TV devices support a low-power mode when the user switches the device off. Instead of shutting down, the device disables the display and keeps Android TV running in the background. Audio output is still enabled in this mode, so your app should stop any currently playing content when the device is in low-power mode.

To avoid playback during low-power mode, override [onStop()](https://developer.android.google.cn/reference/android/app/Activity.html#onStop()) and stop any currently playing content:

@Override
public void onStop() {
  // App-specific method to stop playback
  stopPlayback();
  super.onStop();
}

Ⅲ.Handle controller disconnects

Controllers for TV are frequently Bluetooth devices which may attempt to save power by periodically going into sleep mode and disconnecting from the TV device. This means that an app might be interrupted or restarted if it is not configured to handle these reconnect events. These events can happen in any of the following circumstances:

While watching a video which is several minutes long, a D-Pad or game controller goes into sleep mode, disconnects from the TV device and then reconnects later on.
During gameplay, a new player joins the game using a game controller that is not currently connected.
During gameplay, a player leaves the game and disconnects a game controller.
Any TV app activity that is subject to disconnect and reconnect events must be configured to handle reconnection events in the app manifest. The following code sample demonstrates how to enable an activity to handle configuration changes, including a keyboard or navigation device connecting, disconnecting, or reconnecting:

<activity
  android:name="com.example.android.TvActivity"
  android:label="@string/app_name"
  android:configChanges="keyboard|keyboardHidden|navigation"
  android:theme="@style/Theme.Leanback">

  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
  </intent-filter>
  ...
</activity>

This configuration change allows the app to continue running through a reconnection event, rather than being restarted by the Android framework, which is not a good user experience.

Handle button events

When the user clicks a button on a controller, your app receives an event with a KeyEvent. The intended behavior for the button might be a media event (like play, pause, or stop) or it could be a TV-type event (like selection or navigation). In order to provide a good user experience, your app should assign consistent behavior to controller buttons.

TV UI events

Buttons that generate these KeyEvents should be handled by the app according to table below.

KeyEvent Behavior
BUTTON_B, BACK Back
BUTTON_SELECT, BUTTON_A, ENTER, DPAD_CENTER, KEYCODE_NUMPAD_ENTER Selection
DPAD_UP, DPAD_DOWN, DPAD_LEFT, DPAD_RIGHT Navigation
Media events

When the user is watching media, buttons that generate these KeyEvents should be handled by app according to table below. If your app is controlling a MediaSession, it should call one of the TransportControls methods as shown below. Note that the selection buttons act as Play/Pause buttons in this context.

KeyEvent TransportControls call Behavior
BUTTON_SELECT, BUTTON_A, ENTER, DPAD_CENTER, KEYCODE_NUMPAD_ENTER pause() Play
BUTTON_START, BUTTON_SELECT, BUTTON_A, ENTER, DPAD_CENTER, KEYCODE_NUMPAD_ENTER pause() Pause
BUTTON_R1 skipToNext() Skip to next
BUTTON_L1 skipToPrevious() Skip to previous
DPAD_RIGHT, BUTTON_R2, AXIS_RTRIGGER, AXIS_THROTTLE fastForward() Fast forward
DPAD_LEFT, BUTTON_L2, AXIS_LTRIGGER, AXIS_BRAKE rewind() Rewind
No KeyEvent is associated with Stop) stop() Stop

Ⅳ.Build layouts for TV

A TV screen is typically viewed from about 10 feet away, and while it is much larger than most other Android device displays, this type of screen does not provide the same level of precise detail and color as a smaller device. These factors require you to create app layouts with TV devices in mind in order to create a useful and enjoyable user experience.

Use layout themes for TV

Leanback theme

The v17 leanback support library includes Theme.Leanback, a theme for TV activities that provides a consistent visual style. We strongly recommend using this theme for any TV app built with the v17 leanback classes. The following code sample shows how to apply this theme to an activity:

<activity
  android:name="com.example.android.TvActivity"
  android:label="@string/app_name"
  android:theme="@style/Theme.Leanback">

**Caution:**The leanback theme does not include an action bar, since there none in an Android TV app. If your app uses support fragments, like BrowseSupportFragment, your activity must extend FragmentActivity. Do not use AppCompatActivitywhich tries to theme the action bar and produces the error

java.lang.RuntimeException: Unable to start activity ComponentInfo{...} :
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this
activity.
NoTitleBar theme

The title bar is a standard user interface element for Android apps on phones and tablets, but it is not appropriate for TV apps. If you are not using v17 leanback classes, you should apply this theme to your TV activities to suppress the display of a title bar. The following code example from a TV app manifest demonstrates how to apply this theme to remove the display of a title bar:

<application>
  ...

  <activity
    android:name="com.example.android.TvActivity"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.NoTitleBar">
    ...

  </activity>
</application>

Build basic TV layouts

Layouts for TV devices should follow some basic guidelines to ensure they are usable and effective on large screens. Follow these tips to build landscape layouts optimized for TV screens:

  • Build layouts with a landscape orientation. TV screens always display in landscape mode.
  • Put on-screen navigation controls on the left or right side of the screen and save the vertical space for content.
  • Create UIs that are divided into sections, using Fragments, and use view groups like GridView instead of ListView to make better use of the horizontal screen space.
  • Use view groups such as RelativeLayout or LinearLayout to arrange views. This approach allows the system to adjust the position of the views to the size, alignment, aspect ratio, and pixel density of a TV screen.
  • Add sufficient margins between layout controls to avoid a cluttered UI.
Overscan

Screen elements that must be visible to the user at all times should be positioned within the overscan safe area. Adding a 5% margin of 48dp on the left and right edges and 27dp on the top and bottom edges to a layout ensures that screen elements in that layout will be within the overscan safe area.Example:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   >

   <!-- Screen elements that can render outside the overscan safe area go here -->

   <!-- Nested RelativeLayout with overscan-safe margin -->
   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:layout_marginTop="27dp"
       android:layout_marginBottom="27dp"
       android:layout_marginLeft="48dp"
       android:layout_marginRight="48dp">

      <!-- Screen elements that need to be within the overscan safe area go here -->

   </RelativeLayout>
</RelativeLayout>

**Caution:** Do not apply overscan margins to your layout if you are using the v17 leanback classes, such asBrowseFragmentor related widgets, as those layouts already incorporate overscan-safe margins.

Build useable text and controls

The text and controls in a TV app layout should be easily visible and navigable from a distance. Follow these tips to make your user interface elements easier to see from a distance:

  • Break text into small chunks that users can quickly scan.
  • Use light text on a dark background. This style is easier to read on a TV.
  • Avoid lightweight fonts or fonts that have both very narrow and very broad strokes. Use simple sans-serif fonts and anti-aliasing to increase readability.
  • Use Android's standard font sizes:
<TextView
      android:id="@+id/atext"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:gravity="center_vertical"
      android:singleLine="true"
      android:textAppearance="?android:attr/textAppearanceMedium"/>
  • Ensure that all your view widgets are large enough to be clearly visible to someone sitting 10 feet away from the screen (this distance is greater for very large screens). The best way to do this is to use layout-relative sizing rather than absolute sizing, and density-independent pixel (dip) units instead of absolute pixel units. For example, to set the width of a widget, use wrap_content instead of a pixel measurement, and to set the margin for a widget, use dip values instead of px values.

For more information about density-independent pixels and building layouts to handle larger screen sizes, see Supporting multiple screens.

Manage layout resources for TV

The common high-definition TV display resolutions are 720p, 1080i, and 1080p. Your TV layout should target a screen size of 1920 x 1080 pixels, and then allow the Android system to downscale your layout elements to 720p if necessary. In general, downscaling (removing pixels) does not degrade your layout presentation quality. However, upscaling can cause display artifacts that degrade the quality of your layout and have a negative impact on the user experience of your app.
To get the best scaling results for images, provide them as 9-patch image elements if possible. If you provide low quality or small images in your layouts, they will appear pixelated, fuzzy, or grainy, which is not a good experience for the user. Use high-quality images instead.

Handle large bitmaps

TV devices, like any other Android device, have a limited amount of memory. If you build your app layout with very high-resolution images or use many high-resolution images in the operation of your app, it can quickly run into memory limits and cause out of memory errors. To avoid these types of problems, follow these tips:

  • Load images only when they are displayed on the screen. For example, when displaying multiple images in a GridView or Gallery, only load an image when getView() is called on the view's Adapter.
  • Call recycle() on Bitmap views that are no longer needed.
  • Use WeakReference for storing references to Bitmap objects in an in-memory `Collection.
  • If you fetch images from the network, use AsyncTask` to fetch and store them on the device for faster access. Never do network transactions on the application's main user interface thread.
  • Scale down large images to a more appropriate size as you download them; otherwise, downloading the image itself may cause an out of memory exception.
    For more information on getting the best performance when working with images, see Display bitmaps efficiently.

Avoid layout anti-patterns

There are a few approaches to building layouts that you should avoid because they do not work well on TV devices and lead to bad user experiences. Here are some user interface approaches you should specifically not use when developing a layout for TV.

  • Re-using phone or tablet layouts - Do not reuse layouts from a phone or tablet app without modification. Layouts built for other Android device form factors are not well suited for TV devices and should be simplified for operation on a TV.
  • ActionBar - While this user interface convention is recommended for use on phones and tablets, it is not appropriate for a TV interface. In particular, using an action bar options menu (or any pull-down menu for that matter) is strongly discouraged, due to the difficulty in navigating such a menu with a remote control.
  • ViewPager - Sliding between screens can work great on a phone or tablet, but don't try this on a TV!

For more information on designing layouts that are appropriate to TV, see the TV design guide.

Provide effective advertising

For the living room environment, we recommend you use video ads solutions that are full-screen and dismissable within 30 seconds. Functionality for advertising on Android TV, such as dismiss buttons and clickthroughs, must be accessible using the D-pad rather than touch.

Android TV does not provide a web browser. Your ads must not attempt to launch a web browser or redirect to Google Play Store content that is not approved for Android TV devices.
**Note:** You can use theWebViewclass for logins to services like Google+ and Facebook.

Ⅴ.Create TV navigation

Note: You should only use these attributes to modify the navigation order if the default order that the system applies does not work well.
he following code sample shows how to define the next control to receive focus for a TextView layout object:

<TextView android:id="@+id/Category1"
        android:nextFocusDown="@+id/Category2"\>

The following table lists all of the available navigation attributes for Android user interface widgets:

Attribute Function
nextFocusDown Defines the next view to receive focus when the user navigates down.
nextFocusLeft Defines the next view to receive focus when the user navigates left.
nextFocusRight Defines the next view to receive focus when the user navigates right.
nextFocusUp Defines the next view to receive focus when the user navigates up.

To use one of these explicit navigation attributes, set the value to the ID (android:id value) of another widget in the layout. You should set up the navigation order as a loop, so that the last control directs focus back to the first one.

Provide clear focus and selection

The success of an app's navigation scheme on TV devices is depends on how easy it is for a user to determine what user interface element is in focus on screen.
Your app layout and implementation should use color, size, animation, or a combination of these attributes to help users easily determine what actions they can take next. Use a uniform scheme for indicating focus across your application.

Ⅵ.Request background playback

Normally, when the user clicks on Home to display the TV launcher, the activity pauses. However, your app can request background playback, in which the activity continues playing behind the TV launcher.

To request background playback, call requestVisibleBehind(). Be sure to clean up media resources if the activity stops being visible. For example, you should free media resources if requestVisibleBehind() returns false to indicate that the request failed, or if the system calls your override of onVisibleBehindCanceled().

@Override
public void onPause() {
  super.onPause();
  if (mVideoView.isPlaying()) {
    // Argument equals true to notify the system that the activity
    // wishes to be visible behind other translucent activities
    if (! requestVisibleBehind(true)) {
      // App-specific method to stop playback and release resources
      // because call to requestVisibleBehind(true) failed
      stopPlayback();
    }
  } else {
    // Argument equals false because the activity is not playing
    requestVisibleBehind(false);
  }
}

@Override
public void onVisibleBehindCanceled() {
  // App-specific method to stop playback and release resources
  stopPlayback();
  super.onVisibleBehindCanceled();
}

**The methodrequestVisibleBehind()was deprecated in API level 26.** It will be removed in a future release. The functionality described on this page is not supported in Android version 8.0 and later.

错误不足之处或相关建议欢迎大家评论指出,谢谢!如果觉得内容可以的话麻烦喜欢(♥)一下

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,279评论 0 10
  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的阅读 13,422评论 5 6
  • 最近总是觉得近两年自己很不顺当,说是迷信吧,但也是有点依据的。听朋友的建议去看了师傅,嗯。根据原有的名字的确很压运...
    大连李佳桐阅读 244评论 0 0
  • 猎天狩命记.S01E02.巨灵真解 一位壮硕青年,素衣劲装,立于山巅,远远眺望白玉帝京的方向。 他久久沉默不语,心...
    常驻杨家埠的膨于晏阅读 395评论 0 0
  • 今天做阅读终于回到了正常水平,开心~ 当我做完阅读战战兢兢翻开答案的时候,内心是着实提心吊胆了一下的,太刺激了,程...
    吉野佳阅读 200评论 2 1