android - 用于聊天应用程序的自定义数组适配器

标签 android bluetooth android-arrayadapter

我正在创建蓝牙聊天应用程序,我对 Android 编程有点陌生。 Atm 我的应用程序可以管理蓝牙连接和发送/接收数据。 我的问题是用字符串填充 ListView ,因为我不太擅长创建自定义 ArrayAdapter。我有 2 个形状(红色和蓝色气泡)用于发送和接收消息(R.drawable.rounded_corner 和 R.drawable.rounded_corner_get)。我在 Activity (MessengerActivity)中管理蓝牙连接(ConnectedThread),您可以在下面的代码中看到。 因此,如果有人知道如何为给定代码创建自定义 ArrayAdapter 或知道任何其他类似的 StackOverflow 问题,我真的可以使用帮助。

public class MessengerActivity extends AppCompatActivity {
protected static final int MESSAGE_READ = 5;
ConnectedThread mConnectedThhread;
static BluetoothSocket blueSocket;
String nameOfDevice;
public String message;
Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        Log.i("tag", "in handler");
        switch (msg.what) {
            case MESSAGE_READ:
                byte[] readBuf = (byte[]) msg.obj;
                String string = new String(readBuf);
                try {
                    getMessage(string);
                } catch (Exception e) {}
                break;
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_messenger);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    blueSocket = BluetoothSocketGet.blueSocket;
    nameOfDevice = blueSocket.getRemoteDevice().getName();
    toolbar.setTitle(nameOfDevice);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    mConnectedThhread = new ConnectedThread(blueSocket);
    mConnectedThhread.start();

}

public void messageText(View v) {
    EditText edit = (EditText) findViewById(R.id.textMessage);
    String string;
    string = edit.getText().toString();
    edit.setText("");
    mConnectedThhread.write(string.getBytes());
}

public void getMessage(String s) {
    message=s;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_messenger, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    if (id == R.id.action_settings) {
        Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
        startActivity(intent);
    }
    return super.onOptionsItemSelected(item);
}

protected class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {

        mmSocket = socket;

        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        byte[] buffer;  // buffer store for the stream
        int bytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                buffer = new byte[1024];
                bytes = mmInStream.read(buffer);
                // Send the obtained bytes to the UI activity
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();

            } catch (IOException e) {
                break;
            }
        }
    }

    /* Call this from the main activity to send data to the remote device */
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) {
        }
    }

    /* Call this from the main activity to shutdown the connection */
    public void cancel() {
        if (mmInStream != null) {
            try {
                mmInStream.close();
            } catch (IOException e) {
            }
        }
        if (mmOutStream != null) {
            try {
                mmOutStream.close();
            } catch (IOException e) {
            }
        }
        if (mmSocket != null) {
            try {
                mmSocket.close();
            } catch (IOException e) {
            }
        }
    }
}}

MessengerActivity 的 XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.milan.redtooth.MessengerActivityFragment"
tools:showIn="@layout/activity_messenger">

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:transcriptMode="alwaysScroll"
    android:stackFromBottom="true"
    android:layout_weight="1"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:id="@+id/listMessages">
</ListView>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textMessage"
        android:layout_weight="1"
        android:layout_gravity="bottom" />

    <ImageButton
        android:onClick="messageText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/sendMessage"
        android:layout_gravity="bottom"
        android:src="@drawable/ic_send_white_18dp" />

</LinearLayout>

最佳答案

=> 你必须定义两个列表行布局

1). item_send.xml 用于发送消息

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/msgr"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5sp"
            android:layout_gravity="right"
            android:layout_marginBottom="8dp"
            android:layout_marginLeft="20dp"
            android:background="@drawable/ic_send"
            android:shadowColor="@color/textShadow"
            android:shadowDx="1"
            android:shadowDy="1"
            android:text="Medium Texts"
            android:textColor="@color/textColor"
            android:textSize="18sp" />

    </LinearLayout>

2). item_receive.xml 接收消息

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/msgr"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5sp"
            android:layout_marginBottom="5dp"
            android:layout_marginRight="20dp"
            android:background="@drawable/ic_receive"
            android:shadowColor="@color/textShadow"
            android:shadowDx="1"
            android:layout_gravity="left"
            android:shadowDy="1"
            android:text="Medium Text"
            android:textColor="@color/textColor"
            android:textSize="18sp" />

    </LinearLayout>

    [Replace the TextView Background with your own 9 patch bubble image for each row_layout (send and received)]

=> 现在你必须创建自定义数组适配器

    class ChatArrayAdapter extends ArrayAdapter<ChatMessage> {

        private TextView chatText;
        private List<ChatMessage> chatMessageList = new ArrayList<ChatMessage>();
        private Context context;

        @Override
        public void add(ChatMessage object) {
            chatMessageList.add(object);
            super.add(object);
        }

        public ChatArrayAdapter(Context context, int textViewResourceId) {
            super(context, textViewResourceId);
            this.context = context;
        }

        public int getCount() {
            return this.chatMessageList.size();
        }

        public ChatMessage getItem(int index) {
            return this.chatMessageList.get(index);
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ChatMessage chatMessageObj = getItem(position);
            View row = convertView;
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if (chatMessageObj.left) {
                row = inflater.inflate(R.layout.item_send, parent, false);
            } else {
                row = inflater.inflate(R.layout.item_receive, parent, false);
            }
            chatText = (TextView) row.findViewById(R.id.msgr);
            chatText.setText(chatMessageObj.message);
            return row;
        }
    }

=> 在您的主 Activity onCreate() 方法中,只需放置以下代码

ChatArrayAdapter chatArrayAdapter = new ChatArrayAdapter(getApplicationContext(), R.layout.item_send);
    ListView listView = (ListView) findViewById(R.id.listMessage);
    listView.setAdapter(chatArrayAdapter);    
    listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
    listView.setAdapter(chatArrayAdapter);
    //to scroll the list view to bottom on data change
    chatArrayAdapter.registerDataSetObserver(new DataSetObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            listView.setSelection(chatArrayAdapter.getCount() - 1);
        }
    });

=> 在您的主要 Activity 中,只需放置以下方法并在单击按钮时调用它

        private boolean receiveMessage(String msg) {
            chatArrayAdapter.add(new ChatMessage(false, msg));
            return true;
        }


        private boolean sendMessage(String msg) {
            chatArrayAdapter.add(new ChatMessage(true, msg));
            return true;
        }

        enter code here

关于android - 用于聊天应用程序的自定义数组适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37081724/

相关文章:

android - 隐藏/显示 fragmentTransaction 不起作用的 fragment

连接停止时android蓝牙崩溃

Android 永久禁用/启用 Wifi 和蓝牙

Android自定义 ListView 过滤器

android - 使用 ArrayAdapter 在 ListView 中编辑文本

android - 错误 : ArrayAdapter requires the resource ID to be a TextView

android - 编译错误:The method replace in the type FragmentTransaction is not applicable for the arguments ActionBarSherlock

java - 如何在 Java 中为所有单选组中的所有单选按钮设置文本颜色

android - 关闭 expandedView 后 EditText 消失

iphone - GameKit:在没有 GKPeerPickerController 的情况下使用 GKSession 时的连接类型是什么