Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Binding Layout with Dynamic Sublayout (ViewHolder & SubViewHolder)

I am parsing JSON from server to Android and storing data in SQLite in which i have two tables news and news_attachment.

I have done code for displaying news and news_attachment in list but now i want to display multiple attachment for one news.

The following code displaying last_attachment of the particular news. I want to display all attachment with Custom Layout which will be settle automatically in parent view.

NewsAdapter.java

public class NewsAdapter extends SimpleCursorAdapter {

    DatabaseHelper dbHelper;

    LayoutInflater inflater;

    public NewsAdapter(Context context, int layout, Cursor c,
        String[] from, int[] to, int flags) {
    super(context, layout, c, from, to, flags);

    inflater = LayoutInflater.from(context);

    dbHelper = new DatabaseHelper(context);
    dbHelper.open();
    }

    @Override
    public void bindView(View convertView, Context context, Cursor cursor) {

    ViewHolder holder = (ViewHolder) convertView.getTag();

    if(cursor.isNull(cursor.getColumnIndex(DatabaseHelper.NEWS_TITLE))) {
        holder.newsTitleText.setVisibility(View.GONE);
    } else {
        holder.newsTitleText.setVisibility(View.VISIBLE);
        holder.newsTitleText.setText(""+cursor.getString(cursor.getColumnIndex(DatabaseHelper.NEWS_TITLE)));
    }

    if(cursor.isNull(cursor.getColumnIndex(DatabaseHelper.NEWS_TEXT))) {
        holder.newsText.setVisibility(View.GONE);
    } else {
        holder.newsText.setVisibility(View.VISIBLE);
        String newsText = cursor.getString(cursor.getColumnIndex(DatabaseHelper.NEWS_TEXT));
        newsText = Html.fromHtml(newsText).toString();
        holder.newsText.setText(newsText);
    }

    /***************************
     *  Getting Child Cursor... 
     */
    Cursor newsAttachmentCursor;
    int newsId;

    /**
     * Setting up values of news_Attachment Table...
     */
    newsId = cursor.getInt(cursor.getColumnIndex(DatabaseHelper.NEWS_SERVER_ID));
    newsAttachmentCursor = dbHelper.getNewsAttachment(newsId);

    /**
     * Displaying news Attachment
     */
    if(newsAttachmentCursor.getCount() > 0 && newsAttachmentCursor != null){
        newsAttachmentCursor.moveToFirst();

        /**
         * Displaying NEWS_AT_NAME
         */
        if(newsAttachmentCursor.isNull(newsAttachmentCursor.getColumnIndex(DatabaseHelper.NEWS_AT_NAME))) {
        holder.newsAttachment.setVisibility(View.GONE);
        } else{
        holder.newsAttachment.setVisibility(View.VISIBLE);

        /**
         * Displaying If attachment has Images....
         */
        String fileName = newsAttachmentCursor.getString(newsAttachmentCursor.getColumnIndex(DatabaseHelper.NEWS_AT_NAME));
        String fileUrl = newsAttachmentCursor.getString(newsAttachmentCursor.getColumnIndex(DatabaseHelper.NEWS_AT_URL));

        String tempLowerUrl = fileUrl.toLowerCase();
        if(tempLowerUrl != null && (tempLowerUrl.contains("png") || tempLowerUrl.contains("jpeg") || tempLowerUrl.contains("jpg") || tempLowerUrl.contains("ttif") || tempLowerUrl.contains("gif")))
        {
            holder.newsAttachment.setVisibility(View.GONE);
            holder.newsImage.setVisibility(View.VISIBLE);
            Log.d("oopscv2", "File : "+fileUrl);
            new AQuery(mContext).id(holder.newsImage).image(newsAttachmentCursor.getString(newsAttachmentCursor.getColumnIndex(DatabaseHelper.NEWS_AT_URL)), true, true, 0, R.drawable.no_image, null, AQuery.FADE_IN);
        } else {
            holder.newsAttachment.setVisibility(View.VISIBLE);
            holder.newsImage.setVisibility(View.GONE);
            holder.newsAttachment.setText(fileName);    
        }
        }
    } else {
        holder.newsAttachment.setVisibility(View.GONE);
        holder.newsImage.setVisibility(View.GONE);
    }
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
    View v = inflater.inflate(R.layout.frag_news_row, parent, false);
    v.setTag(new ViewHolder(v));
    return v;
    }

    private static class ViewHolder
    {
    TextView newsTitleText;
    TextView newsText;
    ImageView newsImage;
    TextView newsAttachment;

    public ViewHolder(View view) {
        // TODO Auto-generated constructor stub

        newsTitleText   = (TextView) view.findViewById(R.id.newsTitleText);
        newsText        = (TextView) view.findViewById(R.id.newsText);
        newsImage       = (ImageView) view.findViewById(R.id.newsImage);
        newsAttachment  = (TextView) view.findViewById(R.id.newsAttachment);
    }
    }
}

Current Output:

Output

I want dynamic output like (temporary 4 attachment):

enter image description here

I think dynamic view is useful for this but i dont know how to add dynamically view with formatting with onClick listener for all attachment.

Hows its possible.?


Updated Question after solved above question:

Now i have following Updated Adapter:

NewsNewAdapter.java

public class NewsAdapterNew extends SimpleCursorAdapter {

    DatabaseHelper dbHelper;

    LayoutInflater inflater;

    ViewHolder holder;

    ViewHolder.SubViewHolder subHolder;

    String DIRPATH = android.os.Environment.getExternalStorageDirectory() + File.separator + "TEMP" + File.separator;

    public NewsAdapterNew(Context context, int layout, Cursor c,
        String[] from, int[] to, int flags) {
    super(context, layout, c, from, to, flags);

    inflater = LayoutInflater.from(context);

    dbHelper = new DatabaseHelper(context);
    dbHelper.open();
    }

    @Override
    public void bindView(View convertView, final Context context, Cursor cursor) {

    holder = (ViewHolder) convertView.getTag();

    if(cursor.isNull(cursor.getColumnIndex(DatabaseHelper.NEWS_TITLE))) {
        holder.newsTitleText.setVisibility(View.GONE);
    } else {
        holder.newsTitleText.setVisibility(View.VISIBLE);
        holder.newsTitleText.setText(""+cursor.getString(cursor.getColumnIndex(DatabaseHelper.NEWS_TITLE)));
    }

    if(cursor.isNull(cursor.getColumnIndex(DatabaseHelper.NEWS_TEXT))) {
        holder.newsText.setVisibility(View.GONE);
    } else {
        holder.newsText.setVisibility(View.VISIBLE);
        String newsText = cursor.getString(cursor.getColumnIndex(DatabaseHelper.NEWS_TEXT));
        newsText = Html.fromHtml(newsText).toString();
        holder.newsText.setText(newsText);
    }

    /***************************
     *  Getting Child Cursor... 
     */
    Cursor newsAttachmentCursor;
    int newsId;

    /**
     * Setting up values of news_Attachment Table...
     */
    newsId = cursor.getInt(cursor.getColumnIndex(DatabaseHelper.NEWS_SERVER_ID));
    newsAttachmentCursor = dbHelper.getNewsAttachment(newsId);

    Log.d(TAG, "newsAttachmentCursor.getCount() : " +newsAttachmentCursor.getCount());

    /**
     * Displaying news Attachment
     */
    if(newsAttachmentCursor.getCount() > 0 && newsAttachmentCursor != null){
        //newsAttachmentCursor.moveToFirst();

        /**
         * Displaying NEWS_AT_NAME
         */
        holder.layoutAttachment.removeAllViews();

        newsAttachmentCursor.moveToFirst();

        do {

        View viewAttachement = LayoutInflater.from(mContext).inflate(R.layout.attachment_layout, null);

        subHolder = new com.salesman.adapter.NewsAdapterNew.ViewHolder.SubViewHolder(viewAttachement);

        subHolder.newsImage.setTag(subHolder);
        subHolder.newsImageDownload.setTag(subHolder);
        subHolder.newsAttachmentFileName.setTag(subHolder);

        /**
         * Displaying If attachment has Images....
         */
        subHolder.fileName = newsAttachmentCursor.getString(newsAttachmentCursor.getColumnIndex(DatabaseHelper.NEWS_AT_NAME));
        subHolder.fileUrl = newsAttachmentCursor.isNull(newsAttachmentCursor.getColumnIndex(DatabaseHelper.NEWS_AT_URL)) ? "" :  newsAttachmentCursor.getString(newsAttachmentCursor.getColumnIndex(DatabaseHelper.NEWS_AT_URL));

        subHolder.newsAttachmentFileName.setText(subHolder.fileName);

        String tempExt = subHolder.fileUrl.contains(".") ? subHolder.fileUrl.substring(subHolder.fileUrl.lastIndexOf(".")).toLowerCase() : "";

        Log.d(TAG, "Temp Extension : "+tempExt);

        if(!tempExt.isEmpty()) {

            File myFile = new File(DIRPATH + subHolder.fileName);

            if(myFile.exists()) {
            subHolder.newsImageDownload.setVisibility(View.GONE);
            } else {
            subHolder.newsImageDownload.setVisibility(View.VISIBLE);
            }

            if(tempExt != null && tempExt.equals(".mp4") || (tempExt.equals(".jpeg") || tempExt.equals(".jpg") || tempExt.equals(".ttif") || tempExt.equals(".gif") || tempExt.equals(".png")|| tempExt.equals(".pdf")|| tempExt.equals(".docx")|| tempExt.equals(".doc")|| tempExt.equals(".xls")|| tempExt.equals(".xlsx")|| tempExt.equals(".ppt")|| tempExt.equals(".pptx")|| tempExt.equals(".txt")|| tempExt.equals(".zip")))
            {
            subHolder.newsImage.setVisibility(View.VISIBLE);

            if(tempExt.equals(".pdf")) {
                new AQuery(mContext).id(subHolder.newsImage).image(R.drawable.ic_pdf);
            } else if(tempExt.equals(".doc") || tempExt.equals(".docx")) {
                new AQuery(mContext).id(subHolder.newsImage).image(R.drawable.ic_word);
            } else if(tempExt.equals(".xls") || tempExt.equals(".xlsx")) {
                new AQuery(mContext).id(subHolder.newsImage).image(R.drawable.ic_excel);
            } else if(tempExt.equals(".ppt") || tempExt.equals(".pptx")) {
                new AQuery(mContext).id(subHolder.newsImage).image(R.drawable.ic_ppt);
            } else if(tempExt.equals(".txt")) {
                new AQuery(mContext).id(subHolder.newsImage).image(R.drawable.ic_text);
            } else if(tempExt.equals(".zip")) {
                new AQuery(mContext).id(subHolder.newsImage).image(R.drawable.ic_zip);
            } else if(tempExt.equals(".mp4")) {
                new AQuery(mContext).id(subHolder.newsImage).image(R.drawable.ic_video);
            } else {
                subHolder.newsImage.setVisibility(View.VISIBLE);
                new AQuery(mContext).id(subHolder.newsImage).image(subHolder.fileUrl, true, true, 0, R.drawable.no_image, null, AQuery.FADE_IN);
            }
            } else {
            subHolder.newsImage.setVisibility(View.GONE);
            subHolder.newsImageDownload.setVisibility(View.GONE);
            }

            /***
             * 
             */
            subHolder.newsImageDownload.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                com.salesman.adapter.NewsAdapterNew.ViewHolder.SubViewHolder tempHolder = ((com.salesman.adapter.NewsAdapterNew.ViewHolder.SubViewHolder)v.getTag());
                //Toast.makeText(mContext, tempHolder.fileName.toString() + " is Downloading...", Toast.LENGTH_LONG).show();

                if(InternetConnection.checkConnection(context)) {
                tempHolder.newsImageDownload.setVisibility(View.GONE);
                tempHolder.pBar.setVisibility(View.VISIBLE);
                new DownloadFileAsync().execute(tempHolder);
                } else {
                tempHolder.newsImageDownload.setVisibility(View.VISIBLE);
                tempHolder.pBar.setVisibility(View.GONE);
                AlertDialogManager.showAlertDialog(context, "Download failed", "The download was unable to complete. Please try again later.", false);
                }
            }
            });


            subHolder.newsImage.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                try {
                com.salesman.adapter.NewsAdapterNew.ViewHolder.SubViewHolder tempHolder = ((com.salesman.adapter.NewsAdapterNew.ViewHolder.SubViewHolder)v.getTag());

                Toast.makeText(mContext, "Downloaded : " + tempHolder.fileName.toString(), Toast.LENGTH_LONG).show();

                File myFile = new File(DIRPATH + tempHolder.fileName.toString());

                FileOpen.openFile(mContext, myFile);

                } catch (Exception e) {
                // TODO Auto-generated catch block
                Log.d(TAG, "Error While Opening : "+e.getLocalizedMessage());
                }
            }
            });

                /** Adding News Attachment Layout in Parent LinearLayout **/
            holder.layoutAttachment.addView(viewAttachement);
        }

        viewAttachement.setTag(subHolder);

        } while(newsAttachmentCursor.moveToNext());

    } else {
        holder.layoutAttachment.setVisibility(View.GONE);
    }

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
    View v = inflater.inflate(R.layout.frag_news_row, parent, false);
    v.setTag(new ViewHolder(v));
    return v;
    }

    private static class ViewHolder
    {
    TextView newsTitleText;
    TextView newsText;
    LinearLayout layoutAttachment;

    static class SubViewHolder {
        ImageView newsImage,newsImageDownload;
        TextView newsAttachmentFileName;
        ProgressBar pBar;

        String fileUrl;
        String fileName;

        public SubViewHolder(View subView) {
        // TODO Auto-generated constructor stub
        newsImage   = (ImageView) subView.findViewById(R.id.newsImage);
        newsImageDownload =(ImageView) subView.findViewById(R.id.newsImageDownload);
        pBar        = (ProgressBar) subView.findViewById(R.id.newsProgressBar);
        newsAttachmentFileName = (TextView) subView.findViewById(R.id.newsAttachment);
        }
    }

    public ViewHolder(View view) {
        // TODO Auto-generated constructor stub
        newsTitleText   = (TextView) view.findViewById(R.id.newsTitleText);
        newsText        = (TextView) view.findViewById(R.id.newsText);
        layoutAttachment = (LinearLayout) view.findViewById(R.id.linear_news_row_attachment);
    }
    }
}

frag_new_row.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/newsLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@drawable/bg_white_shadow"
    android:orientation="vertical"
    android:padding="10dp" >

    <TextView
        android:id="@+id/newsTitleText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="3dp"
        android:text="News From"
        android:textColor="@android:color/black"
        android:textSize="@dimen/common_title_textview"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/newsText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="News Text News Text"
        android:textColor="@android:color/black"
        android:textSize="@dimen/common_fontsize" />

    <LinearLayout
        android:id="@+id/linear_news_row_attachment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    </LinearLayout>

</LinearLayout>

Problem:

While scrolling sometimes all News Attachment per News going to blank. I think this problem occurring in adapter while binding view but i cant found.

You will more understand this by following images.

Output Before Scrolling:

Before Scrolling

Output After Scrolling:

After Scrolling

Is my adapter code is wrong? What mistake i have done in Adapter?

Your help would be appreciated.

Thanks & Regards,

Pratik

like image 239
Pratik Butani Avatar asked Apr 17 '14 07:04

Pratik Butani


1 Answers

The easiest way to achieve your goal is to add view for each attachment programmatically. You must do smth like this: make holder.newsAttachments - linearLayout, for example.

Then in your bindView method:

holder.newsAttachment.removeAllViews(); //remove views if it exists
while (newsAttachmentCursor.moveToNext()) {
  View view = LayoutInflater.from(context).inflate(R.layout.layout_for_attachment, null);

  //fill view
  String fileName = newsAttachmentCursor.getString(newsAttachmentCursor.getColumnIndex(DatabaseHelper.NEWS_AT_NAME));
  view.setTag(fileName); // add as tag something, what you need inside onCLickListener
  ((TextView) view.findViewById(R.id.attachment_view_name)).setText(fullName);
  holder.newsAttachment.addView(view);
  view.setOnClickListener(new OnClickListener() {
    @Override
    void onClick(View v) {
       String fileName = (String) v.getTag();
       //do what you want with file name, or anything what you've added to tag.
    }
  });
}

It's only example, but this idea will works fine for small amount of attachments.

like image 166
Alexander Mikhaylov Avatar answered Nov 04 '22 11:11

Alexander Mikhaylov