Статьи

Интерфейс Android: взгляд на приложение с открытым исходным кодом iosched

Так что да, открытый исходный код – это правильно, здорово и помогает каждому научиться делать правильные вещи (или даже просто узнать больше о какой-то платформе). На этой неделе мне нужно было взглянуть на исходный код двух приложений с открытым исходным кодом для Android: iosched и ubuntu one для Android . Они оба довольно хороши, и они заслуживают внимания и более внимательного изучения их исходного кода. Теперь я расскажу вам о хорошей реализации, которую я нашел в приложении IOSched. Шаблон SinglePane. Я действительно не нашел это очень полезным в первый раз, но когда вы начинаете использовать его, вы находите это действительно круто! Он предоставляет вам простой способ определить действия, которые имеют только один фрагмент для своего содержимого. Просто, а?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package com.google.android.apps.iosched.ui;
 
import com.google.android.apps.iosched.R;
 
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
 
/**
 * A {@link BaseActivity} that simply contains a single fragment. The intent used to invoke this
 * activity is forwarded to the fragment as arguments during fragment instantiation. Derived
 * activities should only need to implement {@link SimpleSinglePaneActivity#onCreatePane()}.
 */
public abstract class SimpleSinglePaneActivity extends BaseActivity {
    private Fragment mFragment;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_singlepane_empty);
 
        if (getIntent().hasExtra(Intent.EXTRA_TITLE)) {
            setTitle(getIntent().getStringExtra(Intent.EXTRA_TITLE));
        }
 
        final String customTitle = getIntent().getStringExtra(Intent.EXTRA_TITLE);
        setTitle(customTitle != null ? customTitle : getTitle());
 
        if (savedInstanceState == null) {
            mFragment = onCreatePane();
            mFragment.setArguments(intentToFragmentArguments(getIntent()));
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.root_container, mFragment, "single_pane")
                    .commit();
        } else {
            mFragment = getSupportFragmentManager().findFragmentByTag("single_pane");
        }
    }
 
    /**
     * Called in <code>onCreate</code> when the fragment constituting this activity is needed.
     * The returned fragment's arguments will be set to the intent used to invoke this activity.
     */
    protected abstract Fragment onCreatePane();
 
    public Fragment getFragment() {
        return mFragment;
    }
}

Хотя на этот раз он расширяется от BaseActivity, вы можете расширить его от Activity, SherlockFragmentActivity, RoboSherlockFragmentActivity или любого другого, подходящего вашему проекту. Просто учтите, что он должен уметь использовать фрагменты.

Как вы видите, это довольно просто, вам просто нужно расширить этот класс и переопределить onCreatePane () для вашего дочернего действия.

01
02
03
04
05
06
07
08
09
10
11
12
13
public class ExampleOneFragmentActivity extends SinglePaneActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
 
    @Override
    protected Fragment onCreatePane() {
        return new ExampleOneFragment();
    }
 
}

и это будет фрагмент:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <LinearLayout android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/content_padding_normal"
        android:paddingRight="@dimen/content_padding_normal"
        android:paddingTop="@dimen/content_padding_normal"
        android:paddingBottom="@dimen/content_padding_normal">
 
        <TextView android:id="@+id/vendor_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@style/TextHeader" />
 
        <TextView android:id="@+id/vendor_url"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:autoLink="web"
            android:paddingBottom="@dimen/element_spacing_normal"
            style="@style/TextBody" />
 
        <com.google.android.apps.iosched.ui.widget.BezelImageView android:id="@+id/vendor_logo"
            android:scaleType="centerCrop"
            android:layout_width="@dimen/vendor_image_size"
            android:layout_height="@dimen/vendor_image_size"
            android:layout_marginTop="@dimen/element_spacing_normal"
            android:src="@drawable/sandbox_logo_empty"/>
 
        <TextView android:id="@+id/vendor_desc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/element_spacing_normal"
            android:paddingTop="@dimen/element_spacing_normal"
            style="@style/TextBody" />
    </LinearLayout>
</ScrollView>

* Этот выбран из iosched

Не забывайте, что этот простой шаблон также предоставляет дополнительные возможности для установки нового заголовка! Или вы можете использовать эти два метода из BaseActivity для передачи аргументов из действий во фрагменты.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
     * Converts an intent into a {@link Bundle} suitable for use as fragment arguments.
     */
    public static Bundle intentToFragmentArguments(Intent intent) {
        Bundle arguments = new Bundle();
        if (intent == null) {
            return arguments;
        }
 
        final Uri data = intent.getData();
        if (data != null) {
            arguments.putParcelable("_uri", data);
        }
 
        final Bundle extras = intent.getExtras();
        if (extras != null) {
            arguments.putAll(intent.getExtras());
        }
 
        return arguments;
    }
 
    /**
     * Converts a fragment arguments bundle into an intent.
     */
    public static Intent fragmentArgumentsToIntent(Bundle arguments) {
        Intent intent = new Intent();
        if (arguments == null) {
            return intent;
        }
 
        final Uri data = arguments.getParcelable("_uri");
        if (data != null) {
            intent.setData(data);
        }
 
        intent.putExtras(arguments);
        intent.removeExtra("_uri");
        return intent;
    }

Ссылка: Android UI: взгляните на iosched приложение с открытым исходным кодом от нашего партнера по JCG Хавьера Мансано в блоге Хавьера Мансано в блоге.