7

When my StackedWidget view was only a textview, it displayed on the launcher screen, but with a more intricate layout (A RelativeLayout, imageview, textviews) it does not display anything

Is there something I need to know about setting RemoteViews ?

widget_item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_item"
android:layout_width="270dp"
android:layout_height="150dp">

<ImageView
    android:id="@+id/timelineCellImage"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true"
    android:onClick="onClick"
    android:scaleType="centerCrop"
    android:src="@drawable/bottom_grey_gradient"
   />

<LinearLayout
    android:id="@+id/timelineCellTextHolder"
    android:layout_width="match_parent"
    android:layout_height="@dimen/fifty_dp"
    android:layout_alignBottom="@id/timelineCellImage"
    android:layout_alignLeft="@id/timelineCellImage"
    android:background="@drawable/rounded_edges_bottom_dark"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginLeft="@dimen/five_dp"
        android:layout_marginRight="@dimen/five_dp"
        android:layout_marginTop="@dimen/ten_dp"
        android:layout_weight=".5"
        android:ellipsize="end"
        android:gravity="bottom"
        android:lines="1"
        android:text="Test"
        android:textColor="@color/white"
        android:textSize="@dimen/twelve_sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/subheading"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginBottom="@dimen/ten_dp"
        android:layout_marginLeft="@dimen/five_dp"
        android:layout_marginRight="@dimen/five_dp"
        android:layout_weight=".5"
        android:ellipsize="end"
        android:gravity="top"
        android:lines="1"
        android:text="Subtest"
        android:textColor="@color/white"
        android:textSize="@dimen/twelve_sp" />
</LinearLayout>

StackWidgetService.java $getViewAt(int)

public RemoteViews getViewAt(int position) {
    // position will always range from 0 to getCount() - 1.
    RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
    if(!mWidgetItems.isEmpty()){
        // We construct a remote views item based on our widget item xml file, and set the
        // text based on the position.

        rv.setTextViewText(R.id.title, mWidgetItems.get(position).getTitle()); //probably only top stories items, editorial stuff
        rv.setTextViewText(R.id.subheading, mWidgetItems.get(position).getLinkAbstract());
        rv.setImageViewUri(R.id.timelineCellImage, Uri.parse(mWidgetItems.get(position).getCoverImageUrl()));

        // Next, we set a fill-intent which will be used to fill-in the pending intent template
        // which is set on the collection view in StackWidgetProvider.
        Bundle extras = new Bundle();
        extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
        Intent fillInIntent = new Intent();
        fillInIntent.putExtras(extras);
        rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);

        // You can do heaving lifting in here, synchronously. For example, if you need to
        // process an image, fetch something from the network, etc., it is ok to do it here,
        // synchronously. A loading view will show up in lieu of the actual contents in the
        // interim.
        /*new ImageRequest(
                url,
                listener,
                maxWidth,
                maxHeight,
                decodeConfig,
                errorListener);

        Response.Listener<Bitmap> listener = new Response.Listener<Bitmap>() {
            @Override
            public void onResponse(Bitmap bitmap) {
                // use your bitmap
            }
        };*/

    }
    else
    {
        rv.setTextViewText(R.id.title, "my title"); 
        rv.setTextViewText(R.id.subheading, "");
        rv.setImageViewResource(R.id.timelineCellImage, R.drawable.top_grey_gradient);

        Bundle extras = new Bundle();
        extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
        Intent fillInIntent = new Intent();
        fillInIntent.putExtras(extras);
        rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
    }

    try {
        System.out.println("Loading view " + position);
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    // Return the remote views object.
    return rv;
}
CQM
  • 42,592
  • 75
  • 224
  • 366
  • Share the xml layout and the code used to add the inflated layout to the RemoteView. – Manish Mulimani May 29 '14 at 15:51
  • `getCoverImageUrl` does it return content URI? `setImageViewUri` works with content URI and not network resource. If you are using network resource, then you need to set bitmap. Also remove `onClick` and `clickable` attributes of ImageView from layout file. – Manish Mulimani May 30 '14 at 01:57

1 Answers1

5

If you are using local image, use RemoteViews.setImageViewUri.

String url = new File(mWidgetItems.get(position).getCoverImageUrl()).toString();
rv.setImageViewUri(R.id.timelineCellImage, Uri.parse(url));

If you are using network resource, use RemoteViews.setImageViewBitmap.

   Bitmap bm = getImageBitmap(mWidgetItems.get(position).getCoverImageUrl());
   rv.setImageViewBitmap(R.id.timelineCellImage, bm);

   // Helper method to get Image bitmap
   private Bitmap getImageBitmap(String purl) {
        Bitmap bm = null;
        try {
            URL url = new URL(purl);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.connect();
            try {
                InputStream in = new BufferedInputStream( urlConnection.getInputStream() );
                bm = BitmapFactory.decodeStream(in);
            } finally {
                urlConnection.disconnect();
            }
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 

        return bm;
    }

Remove clickable and onClick attributes from ImageView. onClick attribute results in adding setOnClickListener. You can refer to this answer I had written earlier. If you want to handle click event on ImageViewin case of remote views, you should be using RemoteViews.setOnClickPendingIntent.

Community
  • 1
  • 1
Manish Mulimani
  • 17,535
  • 2
  • 41
  • 60
  • maybe, this is possible but I think I just need to start over on my stackwidget, even removing the image component still doesn't have the widget cells render any longer. And I used to be able to at least display text – CQM Jun 05 '14 at 23:03
  • @CQM Using the Android sample app and the code you had shared, I was able to display the image. I have committed my project to the [git repository](https://github.com/manishcm/StackWidget/archive/master.zip). You can give a try. – Manish Mulimani Jun 05 '14 at 23:37
  • How do I do this network call in a thread in a widget, I tried to put the bitmap assignment in a thread and saving those bitmaps to a hashmap, but no luck setting them to a key – CQM Jun 06 '14 at 21:42