📌  相关文章
📜  如何添加 Android 应用程序的小部件?

📅  最后修改于: 2022-05-13 01:54:19.536000             🧑  作者: Mango

如何添加 Android 应用程序的小部件?

众所周知,手机上安装的许多安卓应用程序都包含小部件。最常见的示例是日历和时钟小部件。那么这些小部件是什么?小部件只是一个位于主屏幕上的迷你应用程序,除了通常出现在主屏幕上的小型启动器图标。小部件确实占用更多空间并显示应用程序的最新信息。其中一些也是用户可调整大小的。小部件最常见的用例是启动应用程序或它的某些特定活动。

小部件基本上是使用接收器与应用程序通信的广播消息,因此您还必须将其包含到您的清单文件中。这似乎需要做很多工作,感谢 Android Studio,它可以为我们完成所有这些工作。所以,只需去 Android Studio 点击app->New->Widget->AppWidget 。给它一个名字,你就完成了小部件的设置。您甚至可以检查它是否在安装后将拥有自己的带有 Simple TextView 的小部件。

现在,在简要解释了小部件是什么之后,让我们深入了解如何创建它。设置应用程序的小部件分为三个步骤。

  • 第 1 步:一个 WidgetProviderClass 说,MyWidget,它扩展了 AppWidgetProvider 类。
  • 第 2 步:一个 WidgetProviderInfo,它是一个描述 Widget 元数据的 XML,包括最小高度和宽度等信息。
  • 第 3 步:一个小部件布局文件,它将描述您的小部件的外观,但它受到其他布局文件的限制。

主活动文件

现在让我们来创建我们自己的现在需要编码的自定义小部件。在 res 目录的 Layout 文件夹中按以下方式创建一个MainActivity.xml文件,其中包含一个 Listview。

XML
<--!MainActivity.xml-->

   
     
    


Java
import android.appwidget.AppWidgetManager;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
 
public class DetailsActivity extends AppCompatActivity {
    TextView name, content;
    ImageView addToWidget;
    boolean added = false;
 
    // Take your steps of food processing as String variables
    // recipe1 and recipe2.
    private String recipe1
        = "Step1: Take a Lemon and required no of glasses of water" +
          "Step2: Squeeze out the lemon juice into glasses,stir well" +
          "and put iceCubes before serve";
    private String recipe2
        = "Step1: Take a bread and apply some butter on it" +
          "Step2:Put it in the toaster and it is ready";
    ArrayList steps = new ArrayList();
    public static Recipe recipe;
    AppWidgetManager appWidgetManager;
    int appWidgetId;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
 
        // attach xml file for detailsActivity,that will
        // show detail of every food item
        setContentView(R.layout.activity_details);
 
        // Add Steps into step ArrayList
        steps.add(recipe1);
        steps.add(recipe2);
        addToWidget = findViewById(R.id.addToWidget);
 
        // AppWidgetManager manages creating and updating
        // the multiple widgets an application can have.
        appWidgetManager = AppWidgetManager.getInstance(
            DetailsActivity.this);
        appWidgetId = 1;
 
        // Each AppWidget has a different appWidgetId to
        // make it unique.
        name = findViewById(R.id.name);
        content = findViewById(R.id.steps);
        final String heading
            = getIntent().getStringExtra("name");
        final int pos = getIntent().getIntExtra("pos", -1);
        recipe = new Recipe(heading, steps.get(pos));
        name.setText(heading);
        content.setText(steps.get(pos));
 
        // Attach clickListener on ImageView Object so when
        // we will click it will handle the widget adding
        // code.
        addToWidget.setOnClickListener(
            new View.OnClickListener() {
                @Override public void onClick(View view)
                {
                    added
                        = !added; // boolean variable to
                                  // know the state ,if
                                  // widget is added or not.
                    Toast
                        .makeText(DetailsActivity.this,
                                  "Click",
                                  Toast.LENGTH_SHORT)
                        .show();
                    if (added) {
                        // Calling updateAppWidget static
                        // method of RecipeWidget to update
                        // widgets of app
                        RecipeWidget.updateAppWidget(
                            DetailsActivity.this,
                            appWidgetManager, appWidgetId,
                            recipe);
                        Toast
                            .makeText(DetailsActivity.this,
                                      "Added to Widget",
                                      Toast.LENGTH_SHORT)
                            .show();
                        addToWidget.setImageDrawable(
                            getResources().getDrawable(
                                R.drawable.add_widget));
                    }
                    else {
 
                        addToWidget.setImageDrawable(
                            getResources().getDrawable(
                                R.drawable.not_widget));
                        RecipeWidget.updateAppWidget(
                            DetailsActivity.this,
                            appWidgetManager, appWidgetId,
                            null);
                    }
                }
            });
    }
    // This method was created to pass Recipe object
    // information to AppWidget.
    public static Recipe getRecipe() { return recipe; }
}


XML
<--!DetailsActivity.xml>


       
    
    
     
    
    
       
      
    
 


Java
import android.appwidget.AppWidgetManager;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
 
public class DetailsActivity extends AppCompatActivity {
    TextView name, content;
    ImageView addToWidget;
    boolean added = false;
 
    // Take your steps of food processing as String variables
    // recipe1 and recipe2.
    private String recipe1
        = "Step1: Take a Lemon and required no of glasses of water" +
          "Step2: Squeeze out the lemon juice into glasses,stir well" +
          "and put iceCubes before serve";
    private String recipe2
        = "Step1: Take a bread and apply some butter on it" +
          "Step2:Put it in the toaster and it is ready";
    ArrayList steps = new ArrayList();
    public static Recipe recipe;
    AppWidgetManager appWidgetManager;
    int appWidgetId;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
 
        // attach xml file for detailsActivity,that will
        // show detail of every food item
        setContentView(R.layout.activity_details);
 
        // Add Steps into step ArrayList
        steps.add(recipe1);
        steps.add(recipe2);
        addToWidget = findViewById(R.id.addToWidget);
 
        // AppWidgetManager manages creating and updating
        // the multiple widgets an application can have.
        appWidgetManager = AppWidgetManager.getInstance(
            DetailsActivity.this);
        appWidgetId = 1;
 
        // Each AppWidget has a different appWidgetId to
        // make it unique.
        name = findViewById(R.id.name);
        content = findViewById(R.id.steps);
        final String heading
            = getIntent().getStringExtra("name");
        final int pos = getIntent().getIntExtra("pos", -1);
        recipe = new Recipe(heading, steps.get(pos));
        name.setText(heading);
        content.setText(steps.get(pos));
 
        // Attach clickListener on ImageView Object so when
        // we will click it will handle the widget adding
        // code.
        addToWidget.setOnClickListener(
            new View.OnClickListener() {
                @Override public void onClick(View view)
                {
                    added
                        = !added; // boolean variable to
                                  // know the state ,if
                                  // widget is added or not.
                    Toast
                        .makeText(DetailsActivity.this,
                                  "Click",
                                  Toast.LENGTH_SHORT)
                        .show();
                    if (added) {
                        // Calling updateAppWidget static
                        // method of RecipeWidget to update
                        // widgets of app
                        RecipeWidget.updateAppWidget(
                            DetailsActivity.this,
                            appWidgetManager, appWidgetId,
                            recipe);
                        Toast
                            .makeText(DetailsActivity.this,
                                      "Added to Widget",
                                      Toast.LENGTH_SHORT)
                            .show();
                        addToWidget.setImageDrawable(
                            getResources().getDrawable(
                                R.drawable.add_widget));
                    }
                    else {
 
                        addToWidget.setImageDrawable(
                            getResources().getDrawable(
                                R.drawable.not_widget));
                        RecipeWidget.updateAppWidget(
                            DetailsActivity.this,
                            appWidgetManager, appWidgetId,
                            null);
                    }
                }
            });
    }
    // This method was created to pass Recipe object
    // information to AppWidget.
    public static Recipe getRecipe() { return recipe; }
}


Java
package com.tanya.widgettutorial;
 
public class Recipe {
    // The recipe include name of food item and steps to
    // cook it.
    private String name;
    private String steps;
    public Recipe(String name, String steps)
    {
        this.name = name;
        this.steps = steps;
    }
    // Getters and Setters
    public String getName() { return name; }
 
    public void setName(String name) { this.name = name; }
 
    public String getSteps() { return steps; }


Java
package com.tanya.widgettutorial;
 
public class Recipe {
    // The recipe include name of food item and steps to
    // cook it.
    private String name;
    private String steps;
    public Recipe(String name, String steps)
    {
        this.name = name;
        this.steps = steps;
    }
    // Getters and Setters
    public String getName() { return name; }
 
    public void setName(String name) { this.name = name; }
 
    public String getSteps() { return steps; }


  • 现在创建一个Java文件,初始化所有视图并设置 Listview,同时用项目填充它。
  • 将Java文件命名为MainActivity。Java

Java

import android.appwidget.AppWidgetManager;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
 
public class DetailsActivity extends AppCompatActivity {
    TextView name, content;
    ImageView addToWidget;
    boolean added = false;
 
    // Take your steps of food processing as String variables
    // recipe1 and recipe2.
    private String recipe1
        = "Step1: Take a Lemon and required no of glasses of water" +
          "Step2: Squeeze out the lemon juice into glasses,stir well" +
          "and put iceCubes before serve";
    private String recipe2
        = "Step1: Take a bread and apply some butter on it" +
          "Step2:Put it in the toaster and it is ready";
    ArrayList steps = new ArrayList();
    public static Recipe recipe;
    AppWidgetManager appWidgetManager;
    int appWidgetId;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
 
        // attach xml file for detailsActivity,that will
        // show detail of every food item
        setContentView(R.layout.activity_details);
 
        // Add Steps into step ArrayList
        steps.add(recipe1);
        steps.add(recipe2);
        addToWidget = findViewById(R.id.addToWidget);
 
        // AppWidgetManager manages creating and updating
        // the multiple widgets an application can have.
        appWidgetManager = AppWidgetManager.getInstance(
            DetailsActivity.this);
        appWidgetId = 1;
 
        // Each AppWidget has a different appWidgetId to
        // make it unique.
        name = findViewById(R.id.name);
        content = findViewById(R.id.steps);
        final String heading
            = getIntent().getStringExtra("name");
        final int pos = getIntent().getIntExtra("pos", -1);
        recipe = new Recipe(heading, steps.get(pos));
        name.setText(heading);
        content.setText(steps.get(pos));
 
        // Attach clickListener on ImageView Object so when
        // we will click it will handle the widget adding
        // code.
        addToWidget.setOnClickListener(
            new View.OnClickListener() {
                @Override public void onClick(View view)
                {
                    added
                        = !added; // boolean variable to
                                  // know the state ,if
                                  // widget is added or not.
                    Toast
                        .makeText(DetailsActivity.this,
                                  "Click",
                                  Toast.LENGTH_SHORT)
                        .show();
                    if (added) {
                        // Calling updateAppWidget static
                        // method of RecipeWidget to update
                        // widgets of app
                        RecipeWidget.updateAppWidget(
                            DetailsActivity.this,
                            appWidgetManager, appWidgetId,
                            recipe);
                        Toast
                            .makeText(DetailsActivity.this,
                                      "Added to Widget",
                                      Toast.LENGTH_SHORT)
                            .show();
                        addToWidget.setImageDrawable(
                            getResources().getDrawable(
                                R.drawable.add_widget));
                    }
                    else {
 
                        addToWidget.setImageDrawable(
                            getResources().getDrawable(
                                R.drawable.not_widget));
                        RecipeWidget.updateAppWidget(
                            DetailsActivity.this,
                            appWidgetManager, appWidgetId,
                            null);
                    }
                }
            });
    }
    // This method was created to pass Recipe object
    // information to AppWidget.
    public static Recipe getRecipe() { return recipe; }
}

输出:

输出画面

详细活动文件

现在,我们在食谱列表中添加了两个项目,每个项目都包含一个附加的 clicklistener,它将导航到DetailsActivity。 Java具有通过意图传递的预期信息。以下是DetailsActivity.xml的布局,其中包含两个 textview 和一个 AddWidget Button(ImageView)。

XML

<--!DetailsActivity.xml>


       
    
    
     
    
    
       
      
    
 

  • 创建AppWidgetManager对象的实例。
  • 给它一个 id,即AppWidgetId ,使其独一无二。
  • 使用app->new->vector 资产->选择您希望图像显示的可绘制对象,就像我们选择了星形矢量( R.drawable.addToWidget )一样。

Java

import android.appwidget.AppWidgetManager;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
 
public class DetailsActivity extends AppCompatActivity {
    TextView name, content;
    ImageView addToWidget;
    boolean added = false;
 
    // Take your steps of food processing as String variables
    // recipe1 and recipe2.
    private String recipe1
        = "Step1: Take a Lemon and required no of glasses of water" +
          "Step2: Squeeze out the lemon juice into glasses,stir well" +
          "and put iceCubes before serve";
    private String recipe2
        = "Step1: Take a bread and apply some butter on it" +
          "Step2:Put it in the toaster and it is ready";
    ArrayList steps = new ArrayList();
    public static Recipe recipe;
    AppWidgetManager appWidgetManager;
    int appWidgetId;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
 
        // attach xml file for detailsActivity,that will
        // show detail of every food item
        setContentView(R.layout.activity_details);
 
        // Add Steps into step ArrayList
        steps.add(recipe1);
        steps.add(recipe2);
        addToWidget = findViewById(R.id.addToWidget);
 
        // AppWidgetManager manages creating and updating
        // the multiple widgets an application can have.
        appWidgetManager = AppWidgetManager.getInstance(
            DetailsActivity.this);
        appWidgetId = 1;
 
        // Each AppWidget has a different appWidgetId to
        // make it unique.
        name = findViewById(R.id.name);
        content = findViewById(R.id.steps);
        final String heading
            = getIntent().getStringExtra("name");
        final int pos = getIntent().getIntExtra("pos", -1);
        recipe = new Recipe(heading, steps.get(pos));
        name.setText(heading);
        content.setText(steps.get(pos));
 
        // Attach clickListener on ImageView Object so when
        // we will click it will handle the widget adding
        // code.
        addToWidget.setOnClickListener(
            new View.OnClickListener() {
                @Override public void onClick(View view)
                {
                    added
                        = !added; // boolean variable to
                                  // know the state ,if
                                  // widget is added or not.
                    Toast
                        .makeText(DetailsActivity.this,
                                  "Click",
                                  Toast.LENGTH_SHORT)
                        .show();
                    if (added) {
                        // Calling updateAppWidget static
                        // method of RecipeWidget to update
                        // widgets of app
                        RecipeWidget.updateAppWidget(
                            DetailsActivity.this,
                            appWidgetManager, appWidgetId,
                            recipe);
                        Toast
                            .makeText(DetailsActivity.this,
                                      "Added to Widget",
                                      Toast.LENGTH_SHORT)
                            .show();
                        addToWidget.setImageDrawable(
                            getResources().getDrawable(
                                R.drawable.add_widget));
                    }
                    else {
 
                        addToWidget.setImageDrawable(
                            getResources().getDrawable(
                                R.drawable.not_widget));
                        RecipeWidget.updateAppWidget(
                            DetailsActivity.this,
                            appWidgetManager, appWidgetId,
                            null);
                    }
                }
            });
    }
    // This method was created to pass Recipe object
    // information to AppWidget.
    public static Recipe getRecipe() { return recipe; }
}

输出:

输出画面

食谱。 Java文件

现在,每个食谱都包含一个食谱名称(字符串)和一个食谱步骤(字符串),因此为了便于维护,我们将创建一个食谱对象。

Java

package com.tanya.widgettutorial;
 
public class Recipe {
    // The recipe include name of food item and steps to
    // cook it.
    private String name;
    private String steps;
    public Recipe(String name, String steps)
    {
        this.name = name;
        this.steps = steps;
    }
    // Getters and Setters
    public String getName() { return name; }
 
    public void setName(String name) { this.name = name; }
 
    public String getSteps() { return steps; }


关于小部件你必须知道的三个词:

  • RemoteView:现在,我之前提到小部件布局与任何其他布局相同。因此,基本上,小部件布局基于 RemoteView,因为它们在您的主屏幕上被视为单独的应用程序。 RemoteView 用于描述将在另一个进程中显示的视图层次结构。
  • onUpdate()方法: onUpdate()方法在创建新 Widget 时以及在 Widgetinfo.xml 文件中设置的每个更新间隔期间调用,即在您为 xml 目录下的应用程序创建 Widget 时生成。
  • AppWidgetManager 类:该类包含有关家中存在的小部件的所有信息。它还提供对所有现有小部件的访问强制更新。

食谱小部件。Java

Java

package com.tanya.widgettutorial;
 
public class Recipe {
    // The recipe include name of food item and steps to
    // cook it.
    private String name;
    private String steps;
    public Recipe(String name, String steps)
    {
        this.name = name;
        this.steps = steps;
    }
    // Getters and Setters
    public String getName() { return name; }
 
    public void setName(String name) { this.name = name; }
 
    public String getSteps() { return steps; }

输出:

输出画面