我自己的消息应用适配器

时间:2015-08-08 10:48:38

标签: android baseadapter

我正在开发自己的消息应用程序,用于向/从服务器发送和接收消息。

我正在使用名为状态的整数数组,表示邮件是传出或传入。

当我在 MessageActivity 中的下方评论时,listview会向我显示一些消息,但是当我向下滚动时,我的应用程序崩溃,我得到编舞错误。

holder.ivReceiveUser.setImageBitmap(BitmapFactory.decodeFile(userImage));           

另外,当我不在上面评论时,我得到 BitmapFactory 错误。 (我确定imagePath是真的,因为我在其他活动中使用它)

任何建议都将受到赞赏......

MessageActivity

private void initListview()
{
    lv = (ListView) findViewById(R.id.lv_messages);
    MessagesList = dbh.getAllMessagesOfSpecificUser(TargetUserID);
    final String img = TargetModel.getImagePath();
    String username = TargetModel.getName();
    String[] Content = new String[MessagesList.size()]; 
    String[] MessageID = new String[MessagesList.size()];
    String[] SendDate = new String[MessagesList.size()];
    int[] Status = new int[MessagesList.size()];
    String[] ReadDate = new String[MessagesList.size()];
    for(int i=0; i<MessagesList.size(); i++)
    {
        Content[i] = MessagesList.get(i).getContent(); 
        MessageID[i] = MessagesList.get(i).getMessageID();
        SendDate[i] = MessagesList.get(i).getSendDate();
        Status[i] = MessagesList.get(i).getStatus();
        ReadDate[i] = MessagesList.get(i).getReadDate();
    }       
    mAdapter = new AdapterMessagesII(MessagesActivity.this, MessageID, Content, SendDate, ReadDate, Status, username, img);     
    lv.setAdapter(mAdapter);
}

AdapterMessagesII

package  MyPackageName.Adapters;
import  MyPackageName.R;
import com.pkmmte.circularimageview.CircularImageView;
import android.content.Context;
import android.graphics.Typeface;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

public class AdapterMessagesII extends BaseAdapter {

private LayoutInflater inflater;
private Typeface tf;    
private CharSequence time;
private String[] MessageID; 
private String[] Content;
private String[] SendDate;
private String[] ReadDate;
private int[] Status;   
private String Username;
private String userImage;   

public AdapterMessagesII(Context context, String[] MessageID, String[]   Content, String[] SendDate, String[] ReadDate, int[] Status, String Username, String userImage)
{
    inflater = LayoutInflater.from(context);
    this.MessageID = MessageID;
    this.Content = Content;
    this.SendDate = SendDate;
    this.ReadDate = ReadDate;
    this.Status = Status;   
    this.Username = Username;       
    this.userImage = userImage;
    tf = Typeface.createFromAsset(context.getAssets(),"fonts/MJ_DINAR ONE LIGHT.TTF");      
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return MessageID.length;
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return MessageID[position];
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    ViewHolder holder = null;
    if (convertView == null)
    {
        holder = new ViewHolder();
        switch (Status[position])
        {
        case 0: //Send
            convertView = inflater.inflate(R.layout.list_messages_row_send, null);
            holder.tvSendContent = (TextView) convertView.findViewById(R.id.tv_send_message_content);
            holder.tvSendTimestamp = (TextView) convertView.findViewById(R.id.tv_send_message_timestamp);
            holder.tvSendReadDate = (TextView) convertView.findViewById(R.id.tv_send_message_read_status);              
            holder.layoutReadStatus = (LinearLayout) convertView.findViewById(R.id.layout_send_message_read_status);
            break;
        case 1: //Receive
            convertView = inflater.inflate(R.layout.list_messages_row_receive, null);
            holder.tvUsername = (TextView) convertView.findViewById(R.id.tv_receive_message_username);
            holder.tvReceiveContent = (TextView) convertView.findViewById(R.id.tv_receive_message_content);
            holder.tvReceiveTimestamp = (TextView) convertView.findViewById(R.id.tv_receive_message_timestamp);
            holder.ivReceiveUser = (CircularImageView) convertView.findViewById(R.id.iv_receive_message);
            break;
        }
        convertView.setTag(holder);
    } 
    else
    {
        holder = (ViewHolder) convertView.getTag();
    }


    switch (Status[position])
    {
    case 0: //Send
        holder.tvSendContent.setText(Content[position]);
        time = DateUtils.getRelativeTimeSpanString(Long.parseLong(SendDate[position]),
                System.currentTimeMillis(),DateUtils.SECOND_IN_MILLIS);
        holder.tvSendTimestamp.setText(time);   
        switch(ReadDate[position])
        {           
        case "x": 
            break;
        default:
            holder.layoutReadStatus.setVisibility(View.VISIBLE);
            time = DateUtils.getRelativeTimeSpanString(Long.parseLong(ReadDate[position]),
                    System.currentTimeMillis(),DateUtils.SECOND_IN_MILLIS);
            holder.tvSendReadDate.setText(time);
            break;
        }
        break;
    case 1: //Receive           
        switch(userImage)
        {
        case "x":    holder.ivReceiveUser.setImageResource(R.drawable.avatar_male_dark);
            break;
        default:    holder.ivReceiveUser.setImageBitmap(BitmapFactory.decodeFile(userImage));           
            break;
        }
        holder.tvUsername.setText(Username);
        holder.tvUsername.setTypeface(tf);
        holder.tvReceiveContent.setText(Content[position]);
        time = DateUtils.getRelativeTimeSpanString(Long.parseLong(SendDate[position]),
                System.currentTimeMillis(),DateUtils.SECOND_IN_MILLIS); 
        holder.tvReceiveTimestamp.setText(time);
        break;
    }
    return convertView;
}

static class ViewHolder
{
    TextView tvUsername;
    TextView tvReceiveContent;
    TextView tvReceiveTimestamp;
    CircularImageView ivReceiveUser;
    TextView tvSendContent;
    TextView tvSendTimestamp;
    TextView tvSendReadDate;        
    LinearLayout layoutReadStatus;
}   
}

list_messages_row_receive

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/ MyPackageName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/BackgrounColor"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/layout_receive_messages"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp"
    android:orientation="horizontal"
    android:paddingLeft="5dp" >

    <LinearLayout
        android:id="@+id/qq"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="vertical" >

        <com.pkmmte.circularimageview.CircularImageView
            android:id="@+id/iv_receive_message"
            android:layout_width="45dp"
            android:layout_height="45dp"
            app:border="true"
            app:border_color="@color/LightGray"
            app:border_width="0dp" />

        <TextView
            android:id="@+id/tv_receive_message_timestamp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="@color/messagesTimestamp"
            android:textSize="8sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:gravity="left"
        android:orientation="vertical"
        android:paddingTop="5dp" >

        <TextView
            android:id="@+id/tv_receive_message_username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/colorPrimary"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/tv_receive_message_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:background="@drawable/receive_message"
            android:gravity="right"
            android:lineSpacingMultiplier="1.5"
            android:maxWidth="350dp"
            android:minWidth="35dp"
            android:paddingBottom="5dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="10dp"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/darkGray"
            android:textSize="9sp" />
    </LinearLayout>
</LinearLayout>    
</LinearLayout>

list_messages_row_send

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_send_messages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="@color/BackgrounColor"
android:orientation="vertical" >

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="right"
    android:orientation="horizontal"
    android:paddingRight="5dp" >

    <TextView
        android:id="@+id/tv_send_message_timestamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginRight="5dp"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="@color/messagesTimestamp"
        android:textSize="8sp" />

    <TextView
        android:id="@+id/tv_send_message_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:background="@drawable/send_message"
        android:gravity="right"
        android:lineSpacingMultiplier="1.5"
        android:maxWidth="350dp"
        android:minWidth="35dp"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="10dp"            
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@color/white"
        android:textSize="9sp" />        
</LinearLayout>

<LinearLayout
    android:id="@+id/layout_send_message_read_status"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginRight="5dp"
    android:layout_marginTop="2dp"
    android:gravity="right|center_vertical"
    android:paddingRight="5dp"
    android:visibility="gone"
    android:orientation="horizontal" >

    <ImageView                
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:layout_marginRight="2dp"
        android:src="@drawable/icon_correct" />

    <TextView
        android:id="@+id/tv_send_message_read_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="@color/messagesTimestamp"
        android:textSize="8sp" />        
</LinearLayout>    
</LinearLayout>

更新

这是 Logcat

08-08 16:45:39.604: I/LOG_ITEM_IMG(2872):  /storage/emulated/0/MyAppName/UserImage/010DEC12-A89A-4ACC-B6BE-7FCC677D9526.jpg
08-08 16:45:39.656: D/dalvikvm(2872): GC_FOR_ALLOC freed 1296K, 26% free 43552K/58680K, paused 4ms, total 6ms
08-08 16:45:39.660: I/dalvikvm-heap(2872): Grow heap (frag case) to 55.924MB for 14017548-byte allocation
08-08 16:45:39.664: D/dalvikvm(2872): GC_FOR_ALLOC freed 16K, 3% free 57225K/58680K, paused 7ms, total 7ms
08-08 16:45:39.736: W/Settings(2872): Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
08-08 16:45:39.788: D/dalvikvm(2872): GC_FOR_ALLOC freed 17191K, 32% free 40169K/58680K, paused 6ms, total 6ms
08-08 16:45:39.800: I/dalvikvm-heap(2872): Grow heap (frag case) to 59.047MB for 20756748-byte allocation
08-08 16:45:39.808: D/dalvikvm(2872): GC_FOR_ALLOC freed 1K, 24% free 60438K/78952K, paused 6ms, total 6ms
08-08 16:45:39.860: D/dalvikvm(2872): GC_FOR_ALLOC freed 1K, 20% free 63864K/78952K, paused 4ms, total 4ms
08-08 16:45:39.860: I/dalvikvm-heap(2872): Grow heap (frag case) to 75.760MB for 14017548-byte allocation
08-08 16:45:39.868: D/dalvikvm(2872): GC_FOR_ALLOC freed <1K, 2% free 77553K/78952K, paused 8ms, total 8ms
08-08 16:45:44.380: E/InputEventReceiver(2872): Exception dispatching input event.

更新2:

根据我的想法,错误必须在 list_messages_row_send.xml list_messages_row_receive.xml 布局中,或者在我的适配器中使用它们。

因为当我只将状态为0或1的消息传递给适配器时,滚动列表视图时没有错误。

但是当我传递一条状态为1或0(第一个状态的反转)的消息时,就会发生错误。

2 个答案:

答案 0 :(得分:1)

将此功能添加到适配器:

private Bitmap decodeFile(File f) {
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //The new size we want to scale to
        final int REQUIRED_SIZE=70;

        //Find the correct scale value. It should be the power of 2.
        int scale=1;
        while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2;

        //Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}

来源:Bitmap Out Of Memory Issues

并更改holder.ivReceiveUser.setImageBitmap(BitmapFactory.decodeFile(userImage));

holderholder.ivReceiveUser.setImageBitmap(decodeFile(new File(userImage));

我希望有效

答案 1 :(得分:1)

当您向上和向下滚动时,您创建的图像可能已被垃圾收集,这意味着ListView正在尝试再次重新创建这些图像,这就是它崩溃的原因。

您需要使用Eru LruCache或DiskLruCache缓存图像。

请阅读此Android链接,它会对您有所帮助。

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

public View getView(int position, View convertView,     ViewGroup parent) 
{

ViewHolder holder = null;
if (convertView == null)
{
holder = new ViewHolder();
switch (Status[position])
{
case 0: //Send
convertView = inflater.inflate(R.layout.list_messages_row_send, null);
holder.tvSendContent = (TextView) convertView.findViewById(R.id.tv_send_message_content);
holder.tvSendTimestamp = (TextView) convertView.findViewById(R.id.tv_send_message_timestamp);
holder.tvSendReadDate = (TextView) convertView.findViewById(R.id.tv_send_message_read_status);              
holder.layoutReadStatus = (LinearLayout) convertView.findViewById(R.id.layout_send_message_read_status);
break;
case 1: //Receive
convertView = inflater.inflate(R.layout.list_messages_row_receive, null);
holder.tvUsername = (TextView) convertView.findViewById(R.id.tv_receive_message_username);
holder.tvReceiveContent = (TextView) convertView.findViewById(R.id.tv_receive_message_content);
holder.tvReceiveTimestamp = (TextView) convertView.findViewById(R.id.tv_receive_message_timestamp);
holder.ivReceiveUser = (CircularImageView) convertView.findViewById(R.id.iv_receive_message);
break;
}

convertView.setTag(保持器);     }     其他     {     holder =(ViewHolder)convertView.getTag();     }     开关(状态[位置])     {     case 0://发送     holder.tvSendContent.setText(内容[位置]);     time = DateUtils.getRelativeTimeSpanString(Long.parseLong(SendDate [position]),         System.currentTimeMillis的(),DateUtils.SECOND_IN_MILLIS);     holder.tvSendTimestamp.setText(时间);
    if(ReadDate [position]!= null)     {     holder.layoutReadStatus.setVisibility(View.VISIBLE);     time = DateUtils.getRelativeTimeSpanString(Long.parseLong(ReadDate [position]),                     System.currentTimeMillis的(),DateUtils.SECOND_IN_MILLIS);     holder.tvSendReadDate.setText(时间);     }// 万一     打破;     案例1://收到
     if(userImage!= null)      {holder.ivReceiveUser.setImageResource(R.drawable.avatar_male_dark);     }     其他{     holder.ivReceiveUser.setImageBitmap(BitmapFactory.decodeFile(userImage));     }     holder.tvUsername.setText(用户名);     holder.tvUsername.setTypeface(TF);     holder.tvReceiveContent.setText(内容[位置]);     time = DateUtils.getRelativeTimeSpanString(Long.parseLong(SendDate [position]),     System.currentTimeMillis的(),DateUtils.SECOND_IN_MILLIS);     holder.tvReceiveTimestamp.setText(时间);     打破;     } //结束开关(状态[位置])

return convertView;
}

我将推荐简化和Clarit,创建2个AdapterClasses,如下所示; AdapterClass1 AdapterClass2     class SwitchView扩展了AsyncTask     {     @override     protected void doInBackground(Integer ... params)     {     int whichView = params [0];     开关(whichView)     {     案例0:     //加载AdapterClass 1     打破;     情况1;     //加载AdapterClass 2     打破;     } //结束开关     } //结束doInBackgroud     protected void onPostExecute()     {     //关闭ProgressDialog     }     } //结束SwitchView