android widget笔记

一:实现一个Activity配置widget

(1):在widget配置文件中加入如下代码:

<appwidget-provider
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:minWidth="250dp"
  android:minHeight="180dp"
  android:updatePeriodMillis="0"
  android:initialLayout="@layout/widget_layout"
  android:resizeMode="vertical"
  android:configure="xx.widgets.ExampleAppWidgetConfigure" 
  android:previewImage="@drawable/ic_launcher">
</appwidget-provider>

(2):在Activity中加入如下代码:

Intent launchIntent = getIntent();
Bundle extras = launchIntent.getExtras();
if (extras != null) {
	
	appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
	Intent cancelResultValue = new Intent();
	cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
	//未配置完成返回结果
	setResult(RESULT_CANCELED, cancelResultValue);
} else {
	// only launch if it's for configuration
	// Note: when you launch for debugging, this does prevent this
	// activity from running. We could also turn off the intent
	// filtering for main activity.
	// But, to debug this activity, we can also just comment the
	// following line out.
	finish();
}
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) 
{
					
	Intent resultValue = new Intent();
	resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
	//配置完成返回结果
	setResult(RESULT_OK, resultValue);
					
}

二:如何在RemoteViews中使用ListView

(1):通过RemoteViewsService 渲染器实现

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.IBinder;
import android.os.Looper;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
public class UpdateService extends RemoteViewsService {

	@Override
	public void onStart(Intent intent, int startId) {
		
		super.onCreate();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return super.onBind(intent);
	}

	@Override
	public RemoteViewsFactory onGetViewFactory(Intent intent) {
		return new ListRemoteViewsFactory(this.getApplicationContext(), intent);
	}
	
	
	class ListRemoteViewsFactory implements
			RemoteViewsService.RemoteViewsFactory {

		private final Context mContext;
		private final List<String> mList;

		public ListRemoteViewsFactory(Context context, Intent intent) {
			mContext = context;
			mList = getDataSources();//获取数据源
			if (Looper.myLooper() == null) {
				Looper.prepare();
			}
		}

		@Override
		public void onCreate() {
			
		}

		
		@Override
		public void onDataSetChanged() {

		}

		@Override
		public void onDestroy() {
			
			mList.clear();
		}

		@Override
		public int getCount() {
			
			return mList.size();
		}

		@Override
		public RemoteViews getViewAt(int position) {
			if (position < 0 || position >= mList.size())
				return null;
			String content = mList.get(position);
			final RemoteViews rv = new RemoteViews(mContext.getPackageName(),
					R.layout.row);
			Intent intent = new Intent();
			// TODO
			// intent.setComponent(new ComponentName("包名", "类名"));
			// 与CustomWidget中remoteViews.setPendingIntentTemplate配对使用实现ListView中的Item的点击事件
			rv.setOnClickFillInIntent(R.id.widget_list_item_layout, intent);		
			rv.setTextViewText(android.R.id.text1, content);

			return rv;
		}

		@Override
		public RemoteViews getLoadingView() {
			return null;
		}

		@Override
		public int getViewTypeCount() {
			return 1;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public boolean hasStableIds() {
			return true;
		}
	}
	
	public List<String>getDataSources() {
		List<String> list = new ArrayList<String>();
		......
		return list;
	}
}
(2):在widget的onUpdate中添加代码:

	for (int i = 0; i < appWidgetIds.length; i++) {//如果使用循环,当调试重新运行程序或者重启机器时widget点击事情会失灵
			Intent intent = new Intent(ctxt, WidgetService.class);
			RemoteViews widget = new RemoteViews(ctxt.getPackageName(),
					R.layout.widget);
			widget.setRemoteAdapter(appWidgetIds[i], R.id.words, intent);

			Intent clickIntent = new Intent(ctxt, LoremActivity.class);
			PendingIntent clickPI = PendingIntent.getActivity(ctxt, 0,
					clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
			widget.setPendingIntentTemplate(R.id.words, clickPI);//配合getViewAt方法中的setOnClickFillInIntent实现listView中Item的点击事件

			appWidgetManager.updateAppWidget(appWidgetIds[i], widget);
		}
(3): widget.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/words"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_marginTop="3dp"
  android:layout_marginLeft="3dp"
  android:background="@drawable/widget_frame"
/>

(4):row.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:gravity="center_vertical"
    android:paddingLeft="6dip"
    android:minHeight="?android:attr/listPreferredItemHeight"
/>
三: 如何更新widget

(1):定时更新

在widget配置文件中有这句 android:updatePeriodMillis="0",这种更新方式已经不能使用了,一般定时更新使用AlarmManager,如下代码

  private void setAlarm(Context context, int appWidgetId, int updateRateSeconds) {
        Intent widgetUpdate = new Intent();
        widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { appWidgetId });

        // make this pending intent unique by adding a scheme to it
        widgetUpdate.setData(Uri.withAppendedPath(Uri.parse(ImagesWidgetProvider.URI_SCHEME + "://widget/id/"), String.valueOf(appWidgetId)));
        PendingIntent newPending = PendingIntent.getBroadcast(context, 0, widgetUpdate, PendingIntent.FLAG_UPDATE_CURRENT);

        // schedule the updating
        AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        if (updateRateSeconds >= 0) {
            alarms.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), updateRateSeconds * 1000, newPending);
        } else {
            alarms.cancel(newPending);
        }
    }
(2):事件更新,不通过时间更新widget一般使用广播来更新

public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		if (intent.getAction().equals(
				"com.example.widgettestone.WIDGET_CONTROL")) {
			AppWidgetManager manager = AppWidgetManager.getInstance(context);
			ComponentName thisWidget = new ComponentName(context, TaskPad.class);
			int[] appWidgetIds = manager.getAppWidgetIds(thisWidget);
			manager.notifyAppWidgetViewDataChanged(appWidgetIds,R.id.widget_list);//通知RemoteViews刷新数据,在渲染器中重写onDataSetChanged方法重写获取数据源
		} else {
			super.onReceive(context, intent);
		}

	}
AndroidManifest.xml中widget的配置中添加:
<action android:name="com.example.widgettestone.WIDGET_CONTROL" />

当需要更新的时候发出该广播即可更新:
		Intent intentUpdate = new Intent("com.example.widgettestone.WIDGET_CONTROL");
		context.sendBroadcast(intentUpdate);
四:小问题:

(1):ListView的getview()中重复调用(position重复调用)问题:

网友提供的解决方法:

重写的listview adapter中,在getView()方法中,打印语句时,相同的position打印了多次,修改方法:
将布局文件中ListView的高度改为“fill_parent”
 <ListView
   android:id="@+id/dynamic_list"
   android:layout_height="fill_parent"
   android:layout_width="fill_parent"
   android:scrollbars="vertical"
   android:layout_weight="1"
   android:drawSelectorOnTop="false"    
   android:fadingEdgeLength="0dip"  
   android:divider="@null" 
   android:dividerHeight="0dip"
   android:cacheColorHint="#00000000" 
   android:background="@color/listview_bg_color" />


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 Android 笔记应用的代码示例: 1. 首先,在 AndroidManifest.xml 文件中添加以下权限: ```xml <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> ``` 2. 在 activity_main.xml 中添加一个 EditText 元素和两个 Button 元素,以便用户输入笔记并保存或加载笔记: ```xml <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter note here"/> <Button android:id="@+id/saveButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Save"/> <Button android:id="@+id/loadButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Load"/> ``` 3. 在 MainActivity.java 文件中编写以下代码: ```java import android.os.Bundle; import android.os.Environment; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; public class MainActivity extends AppCompatActivity { EditText editText; Button saveButton, loadButton; String fileName = "note.txt"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = findViewById(R.id.editText); saveButton = findViewById(R.id.saveButton); loadButton = findViewById(R.id.loadButton); saveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String text = editText.getText().toString(); try { File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + fileName); FileOutputStream fos = new FileOutputStream(file); fos.write(text.getBytes()); fos.close(); Toast.makeText(MainActivity.this, "Note saved to " + fileName, Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } } }); loadButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + fileName); FileInputStream fis = new FileInputStream(file); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); } br.close(); fis.close(); editText.setText(sb.toString()); Toast.makeText(MainActivity.this, "Note loaded from " + fileName, Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } } }); } } ``` 4. 运行应用程序并测试保存和加载笔记的功能。 注意:这只是一个简单的笔记应用程序示例,未进行任何输入验证或错误处理。在实际应用程序中,您可能需要添加更多的代码来确保应用程序的稳定性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值