2016-01-04 18 views
8

Zajmuję się tworzeniem widżetów dla mojej aplikacji do notatek.Jak utworzyć widget Androida z opcjami?

Co chcę archiwum jest podobny do colorNote widget:

  1. Wybierz widżet aplikacji uwaga enter image description here

  2. Zezwalaj użytkownikom wybrać listę notatek dostępnych przechowywanych w Sqlite enter image description here

  3. Wyświetl widget z wybraną treścią notatki. enter image description here

mogę wyświetlić prosty widget pokazać proste przesłanie chcę, ale to, co chcę zrobić, to pozwolić użytkownikom wybrać notatkę określić z listy notatek za treść widgetu. Mam ciężkie czasy na znalezienie powiązanych zasobów, jeśli znasz pewne słowo kluczowe w wyszukiwarce, daj mi znać, a ja sam wykonam badania.

Odpowiedz

9

Myślę, że ColorNote używa numeru Widget Configuration Activity. Możesz znaleźć użyteczny przykład na pierwszym łączu (który jest oficjalny) lub (dlaczego nie) również there.

Aby osiągnąć „Dialog” styl, trzeba ustawić widget aktywność konfiguracji jak poniżej:

<activity 
... 
android:theme="@android:style/Theme.Dialog" 
android:excludeFromRecents="true" /> 

Przykład powyżej pochodzi z this answer.

Aby uzyskać więcej informacji na temat projektowania widżetów, przyjrzyj się także there.

Przykład

1) Tworzenie widget_info i umieścić go na RES/folderu xml:

<?xml version="1.0" encoding="utf-8"?> 
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
    android:configure="com.mycompany.app.widgettest.WidgetConfigureActivity" 
    android:initialKeyguardLayout="@layout/widget" 
    android:initialLayout="@layout/widget" 
    android:minHeight="40dp" 
    android:minWidth="40dp" 
    android:resizeMode="horizontal|vertical" 
    android:updatePeriodMillis="86400000" 
    android:widgetCategory="home_screen"> 

</appwidget-provider> 

2) Utwórz swoje widget układ (wziąłem najprostsza):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#09C" 
    android:padding="@dimen/widget_margin"> 

    <TextView 
     android:id="@+id/appwidget_text" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" 
     android:layout_centerVertical="true" 
     android:layout_margin="8dp" 
     android:background="#09C" 
     android:contentDescription="@string/appwidget_text" 
     android:text="@string/appwidget_text" 
     android:textColor="#ffffff" 
     android:textSize="24sp" 
     android:textStyle="bold|italic" /> 

</RelativeLayout> 

Zapraszam do nadania mu własnego stylu mi.

3) Tworzenie widget_configure układ działalność:

<?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="wrap_content" 
    android:orientation="vertical" 
    android:padding="16dp"> 

    <TextView 
     android:id="@+id/text_view" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="8dp" 
     android:text="@string/configure" /> 

    <EditText 
     android:id="@+id/appwidget_text" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:inputType="text" 
     android:layout_below="@+id/text_view"/> 

    <ListView 
     android:id="@+id/list" 
     android:layout_height="wrap_content" 
     android:layout_width="match_parent" 
     android:layout_below="@+id/appwidget_text" 
     android:layout_above="@+id/add_button"> 
    </ListView> 

    <Button 
     android:id="@+id/add_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="8dp" 
     android:text="@string/add_widget" 
     android:layout_alignParentBottom="true" /> 

</RelativeLayout> 

Również tam, jest do ciebie stylu i edytować układ swojej działalności; w powyższym przykładzie dodałem tekst edycji, który utworzy "nową" notatkę (ale nie jest zapisana w bazie danych) i listę z fałszywą zawartością. Od Ciebie zależy, czy zapełnisz listę, oczywiście z bazy danych.

4) Dodaj do oczywistego aktywności konfiguracji widget i dostawcy widget, jak również (wewnątrz aplikacji tag):

 <receiver android:name=".AppWidget"> 
      <intent-filter> 
       <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
      </intent-filter> 

      <meta-data 
       android:name="android.appwidget.provider" 
       android:resource="@xml/widget_info" /> 
     </receiver> 

     <activity 
      android:name=".WidgetConfigureActivity" 
      android:theme="@android:style/Theme.Dialog" 
      android:excludeFromRecents="true"> 
      <intent-filter> 
       <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> 
      </intent-filter> 
     </activity> 

5) tworzą klasę AppWidget która rozszerzy AppWidgetProvider (zawiadomienie konfiguracja widgetu aplikacji jest zaimplementowana i zarządzana w następującej klasie: WidgetConfigureActivity) [Nie dodałem nic specjalnego w tej klasie]:

import android.appwidget.AppWidgetProvider; 
import android.appwidget.AppWidgetManager; 
import android.content.Context; 
import android.widget.RemoteViews; 

/** 
* Implementation of App Widget functionality. 
*/ 
public class AppWidget extends AppWidgetProvider { 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     // There may be multiple widgets active, so update all of them 
     for (int appWidgetId : appWidgetIds) { 
      updateAppWidget(context, appWidgetManager, appWidgetId); 
     } 
    } 

    @Override 
    public void onDeleted(Context context, int[] appWidgetIds) { 
     // When the user deletes the widget, delete the preference associated with it. 
     for (int appWidgetId : appWidgetIds) { 
      WidgetConfigureActivity.deleteTitlePref(context, appWidgetId); 
     } 
    } 

    @Override 
    public void onEnabled(Context context) { 
     // Enter relevant functionality for when the first widget is created 
    } 

    @Override 
    public void onDisabled(Context context) { 
     // Enter relevant functionality for when the last widget is disabled 
    } 

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, 
           int appWidgetId) { 

     CharSequence widgetText = WidgetConfigureActivity.loadTitlePref(context, appWidgetId); 
     // Construct the RemoteViews object 
     RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget); 
     views.setTextViewText(R.id.appwidget_text, widgetText); 

     // Instruct the widget manager to update the widget 
     appWidgetManager.updateAppWidget(appWidgetId, views); 
    } 
} 

6) Wreszcie, jest to WidgetConfigureActivity:

import android.app.Activity; 
import android.appwidget.AppWidgetManager; 
import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.EditText; 
import android.widget.ListView; 

/** 
* The configuration screen for the {@link AppWidget} com.bepatient.app.widgettest.AppWidget. 
*/ 
public class WidgetConfigureActivity extends Activity { 

    int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; 
    EditText mAppWidgetText; 
    private static final String PREFS_NAME = "AppWidget"; 
    private static final String PREF_PREFIX_KEY = "appwidget"; 

    public WidgetConfigureActivity() { 
     super(); 
    } 

    @Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 

     // Set the result to CANCELED. This will cause the widget host to cancel 
     // out of the widget placement if the user presses the back button. 
     setResult(RESULT_CANCELED); 

     setContentView(R.layout.widget_configure); 
     // Set layout size of activity 
     getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 
     mAppWidgetText = (EditText) findViewById(R.id.appwidget_text); 
     findViewById(R.id.add_button).setOnClickListener(mOnClickListener); 
     final ListView listView = (ListView) findViewById(R.id.list); 

     // Defined array values to show in ListView 
     String[] values = new String[] { "Don't forget the milk!", 
       "Do not forget to go get the mother-in-law", 
       "Go to the laundry", 
       "Marise number" 
     }; 

     ArrayAdapter<String> adapter = new ArrayAdapter<>(this, 
       android.R.layout.simple_list_item_1, android.R.id.text1, values); 

     listView.setAdapter(adapter); 

     // ListView Item Click Listener 
     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       // Take ListView clicked item value 
       String widgetText = (String) listView.getItemAtPosition(position); 
       createWidget(getApplicationContext(), widgetText); 
      } 
     }); 

     // Find the widget id from the intent. 
     Intent intent = getIntent(); 
     Bundle extras = intent.getExtras(); 
     if (extras != null) { 
      mAppWidgetId = extras.getInt(
        AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); 
     } 

     // If this activity was started with an intent without an app widget ID, finish with an error. 
     if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { 
      finish(); 
      return; 
     } 

     mAppWidgetText.setText(loadTitlePref(WidgetConfigureActivity.this, mAppWidgetId)); 
    } 

    View.OnClickListener mOnClickListener = new View.OnClickListener() { 
     public void onClick(View v) { 
      final Context context = WidgetConfigureActivity.this; 

      // When the button is clicked, get text 
      String widgetText = mAppWidgetText.getText().toString(); 
      createWidget(context, widgetText); 
     } 
    }; 

    private void createWidget(Context context, String widgetText) { 
     // Store the string locally 
     saveTitlePref(context, mAppWidgetId, widgetText); 

     // It is the responsibility of the configuration activity to update the app widget 
     AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 
     AppWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId); 

     // Make sure we pass back the original appWidgetId 
     Intent resultValue = new Intent(); 
     resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); 
     setResult(RESULT_OK, resultValue); 
     finish(); 
    } 

    // Write the prefix to the SharedPreferences object for this widget 
    static void saveTitlePref(Context context, int appWidgetId, String text) { 
     SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit(); 
     prefs.putString(PREF_PREFIX_KEY + appWidgetId, text); 
     prefs.apply(); 
    } 

    // Read the prefix from the SharedPreferences object for this widget. 
    // If there is no preference saved, get the default from a resource 
    static String loadTitlePref(Context context, int appWidgetId) { 
     SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0); 
     String titleValue = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null); 
     if (titleValue != null) { 
      return titleValue; 
     } else { 
      return context.getString(R.string.appwidget_text); 
     } 
    } 

    static void deleteTitlePref(Context context, int appWidgetId) { 
     SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit(); 
     prefs.remove(PREF_PREFIX_KEY + appWidgetId); 
     prefs.apply(); 
    } 
} 

W tej klasie będzie trzeba zarządzać i wypełnić wszystkie notatki zapisane w aplikacji DB. Po kliknięciu przycisku lub elementu, metoda createWidget zakończy pracę za Ciebie.

zwrócić uwagę na następującą linię:

// Set layout size of activity 
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 

ta musi być wywołana po setContentView() metody, lub Twoja aktywność będzie mały i drobny. Jeśli uruchomisz ten przykład, okaże się, że działanie konfiguracyjne ma prosty styl, więc będziesz musiał stworzyć swój własny styl, zgodnie z interfejsem użytkownika Twojej aplikacji (jeśli chcesz!).

+0

Czy masz przykład pracy? –

+0

@ cwfei Mam tylko mój własny kod, który utworzy prosty widżet podobny do twojego. Stworzę szybki przykład z konfiguracją. – JJ86

+0

To jest to, co chcę, łatwe do zrozumienia, dziękuję :) –

Powiązane problemy