title: Android widget disable listitem nested button onclick
body: <p>I am making an android app which is having a listview with clickable buttons(nested listview). The Homescreen widget of the app is also having almost same layout. </p>
  
  <p>There is need to disable button after click. In the activity, I can easily disable button as:</p>
  
  <pre><code>button.setOnClickListener(new OnClickListener(){
  
                  public void onClick(View v) {
                      // Disable Button
                      v.setEnabled(false);
  
                      // Mark item as not received
                      Toast.makeText(getApplicationContext(), "Button Disabled", Toast.LENGTH_SHORT).show();
                  }
              });
  </code></pre>
  
  <p>For the widget part, I am using <a href="http://developer.android.com/reference/android/widget/RemoteViewsService.RemoteViewsFactory.html" rel="nofollow noreferrer">RemoteViewFactory</a> to setup the listitems with buttons. Code follows:</p>
  
  <pre><code>public class ListProvider implements RemoteViewsFactory {
  .....
  
     public RemoteViews getViewAt(int position) {
        final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.list_row); //The layout of single list row
       remoteView.setTextViewText(R.id.heading, "Some Heading");
       remoteView.setTextViewText(R.id.content, "Some Content");
       Intent fillInIntent = new Intent();
       fillInIntent.putExtra(WidgetProvider.EXTRA_ITEM, position);
       remoteView.setOnClickFillInIntent(R.id.buttonwidget, fillInIntent);
       .....
     }
  .....
  } 
  </code></pre>
  
  <p>Now that the intent on the button has been setup, I can receive it in the WidgetProvider's <code>onReceive()</code> method as:</p>
  
  <pre><code>public class WidgetProvider extends AppWidgetProvider {
     public static final String EXTRA_ITEM = "com.example.android.stackwidget.EXTRA_ITEM";
     public static final String ACTION_START_ACTIVITY = "startActivity";
  
  @Override
      public void onUpdate(Context context, AppWidgetManager appWidgetManager,
              int[] appWidgetIds) {
          final int N = appWidgetIds.length;
          for (int i = 0; i &lt; N; ++i) {
              RemoteViews remoteViews = updateWidgetListView(context,appWidgetIds[i]);
              Intent clickIntent = new Intent(context, WidgetProvider.class);
              clickIntent.setAction(ACTION_START_ACTIVITY);
              PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, clickIntent, 0);
              remoteViews.setPendingIntentTemplate(R.id.listViewWidget, pendingIntent);
  
          }
  
          super.onUpdate(context, appWidgetManager, appWidgetIds);
     }
  
     @Override
      public void onReceive(Context context, Intent intent) {
          // TODO Auto-generated method stub
          int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
          RemoteViews remoteViews = updateWidgetListView(context,appWidgetId);
          ComponentName thisWidget = new ComponentName(context, WidgetProvider.class);
          AppWidgetManager manager = AppWidgetManager.getInstance(context);
  
          //Printing detail of clicked item from widget
          if(ACTION_START_ACTIVITY.equals(intent.getAction())) {
               //Disable the button
               remoteViews.setBoolean(R.id.buttonwidget, "setEnabled", false);
               Toast.makeText(context, "Widget Button Clicked",   Toast.LENGTH_SHORT).show();
          }
          //Update the widget again
          manager.updateAppWidget(thisWidget, remoteViews);
     }
  }
  </code></pre>
  
  <p>This method is also working good except that it updates only the button of first listitem. I want to disable the button of corresponding listitem that is being clicked. So I might be needing a position element. So I thought of getting the intent in RemoteViewsFactory's <code>getViewAt</code> method as it holds the position of listitem. But I am not able to get the intent. Here is the modified code of <code>RemoteViewsFactory</code>:</p>
  
  <pre><code>public RemoteViews getViewAt(int position) {
            final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.list_row); //The layout of single list row
           remoteView.setTextViewText(R.id.heading, "Some Heading");
           remoteView.setTextViewText(R.id.content, "Some Content");
  
           //Get the intent of button here
           if(WidgetProvider.ACTION_START_ACTIVITY.equals(this.remoteIntent.getAction())) {
              Toast.makeText(context, "Listitem Complete Button Clicked: "+position,   Toast.LENGTH_SHORT).show();
          }
  
           Intent fillInIntent = new Intent();
           fillInIntent.putExtra(WidgetProvider.EXTRA_ITEM, position);
           remoteView.setOnClickFillInIntent(R.id.buttonwidget, fillInIntent);
           .....
         }
  </code></pre>
  
  <p>So I hope you guys got the point. How do I set/change the button at some specific position of itemitem?</p>
  
  <p><strong>EDIT:</strong> I applied the solution given below and it got me working. I can now reveive the intents and the corresponding data along with it. I still had one problem left. The button needs to be change to some other image, depending upon the state. In simple sense, the listview needed to be updated, which I did by generating the random number and sending it along with service intent.
  As explained <a href="https://stackoverflow.com/questions/18183415/widget-ui-not-updating-in-response-to-broadcast">here</a>.</p>