Custom ListView adapter repeats itself - Android Software Development

I have a custom listview that pulls from an array, however when I reach a point that I have to scroll down to see more items, the items start to repeat themselves. According to the array, the items are fine and not repeating themselves, it looks like it's just the ListAdapter. Any help is greatly appreciated. I think the getView is really the only problem, but if you need other parts of the code, let me know.
Code:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.row_title);
holder.summary = (TextView) convertView.findViewById(R.id.row_summary);
holder.url = (TextView) convertView.findViewById(R.id.row_link);
convertView.setTag(holder);
String item = CurbAlert.listings[position];
item = item.replace("<br>", "");
String title = item.substring(item.indexOf("<title>") + 16, item.indexOf("</title>") - 3);
String summary = item.substring(item.indexOf("<description>") + 22, item.indexOf("</description>") - 3);
if (summary.length() > 100) { summary = summary.substring(0, 100); summary += "..."; }
holder.title.setText(title);
holder.summary.setText(summary);
holder.url.setText(item.substring(item.indexOf("<link>") + 6, item.indexOf("</link>")));
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}

Try moving everything from line 10 to 17 inclusive until after the if-else statement. You want to setup the views even if you get your holder from getTag().

Related

WM6 - how to Query WLAN "connection" status

I am desperately trying to work around some unknown problem caused by our NDIS IM driver on WM6 and HTC TyTn ( TyTn at least, but most likely other devices as well ). I started some other threads regarding different facets of this problem, and no help is coming. Now I am just trying to work around it.
in short the problem is when power events happen the WLAN will never connect.
The work around is programmatically open the control panel with STControlPanel class and press the down button 1 time then the f1 key ( right dash ). This "presses connect" on the last configured access point. This works around my problem, however, I need to detect when the access point has connected. There is a "connecting" and "connected" message for the access point in this control panel dialog ( control panel # 17 ).
My Question: Is there some way to get this text "connecting" or "connected" from the control panel #17?
I have tried wzc, ndisuio, winsock, and other "non control panel" ways to detect connected state, but the IM problem fools all these methods. The only thing I have ever seen that successfully shows when the problem has occurred is the "connecting"/"connected" status in the control panel 17.
Please Help Someone.
p.s. If I can get this worked around, we sell a commercial grade ndis intermediate driver toolkit letting you easily write plugins without any of the hard driver details. We have redirectors, transparent proxy, tunnelers, virtual adapters, lots of good stuff. Also the same plugin will work on all windows desktop platforms vista - 98, WM5/6 and CE and also linux and solaris...
Hello skk
What about notification API?
Here is the solution (simple concept) for Your problem. Interesting parts are in bold.
SNapiTest.cpp
Code:
#include "stdafx.h"
#include "SNapiTest.h"
#include <windows.h>
#include <commctrl.h>
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE g_hInst; // current instance
HWND g_hWndMenuBar; // menu bar handle
[b]
const DWORD WM_WIFISTATUS = WM_USER + 1;
bool g_connecting;
bool g_connected;
HREGNOTIFY g_hNotify;
HREGNOTIFY g_hNotify2;
[/b]
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE, LPTSTR);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
// Perform application initialization:
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable;
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SNAPITEST));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SNAPITEST));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
TCHAR szTitle[MAX_LOADSTRING]; // title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // main window class name
g_hInst = hInstance; // Store instance handle in our global variable
// SHInitExtraControls should be called once during your application's initialization to initialize any
// of the device specific controls such as CAPEDIT and SIPPREF.
SHInitExtraControls();
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SNAPITEST, szWindowClass, MAX_LOADSTRING);
//If it is already running, then focus on the window, and exit
hWnd = FindWindow(szWindowClass, szTitle);
if (hWnd)
{
// set focus to foremost child window
// The "| 0x00000001" is used to bring any owned windows to the foreground and
// activate them.
SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
return 0;
}
if (!MyRegisterClass(hInstance, szWindowClass))
{
return FALSE;
}
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
// When the main window is created using CW_USEDEFAULT the height of the menubar (if one
// is created is not taken into account). So we resize the window after creating it
// if a menubar is present
if (g_hWndMenuBar)
{
RECT rc;
RECT rcMenuBar;
GetWindowRect(hWnd, &rc);
GetWindowRect(g_hWndMenuBar, &rcMenuBar);
rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
static SHACTIVATEINFO s_sai;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_HELP_ABOUT:
DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
break;
case IDM_OK:
SendMessage (hWnd, WM_CLOSE, 0, 0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CREATE:
SHMENUBARINFO mbi;
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWnd;
mbi.nToolBarId = IDR_MENU;
mbi.hInstRes = g_hInst;
if (!SHCreateMenuBar(&mbi))
{
g_hWndMenuBar = NULL;
}
else
{
g_hWndMenuBar = mbi.hwndMB;
}
// Initialize the shell activate info structure
memset(&s_sai, 0, sizeof (s_sai));
s_sai.cbSize = sizeof (s_sai);
[b]
g_connecting = false;
g_connected = false;
{HRESULT hr = RegistryNotifyWindow(SN_WIFISTATECONNECTING_ROOT,
SN_WIFISTATECONNECTING_PATH, SN_WIFISTATECONNECTING_VALUE,
hWnd, WM_WIFISTATUS, 0, NULL, &g_hNotify);}
{HRESULT hr2 = RegistryNotifyWindow(SN_WIFISTATECONNECTING_ROOT,
SN_WIFISTATECONNECTED_PATH, SN_WIFISTATECONNECTED_VALUE,
hWnd, WM_WIFISTATUS, 0, NULL, &g_hNotify2);}
[/b]
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
[b]
case WM_WIFISTATUS:
{
DWORD newValue = (DWORD) wParam;
WCHAR caption[] = L"Wifi Status";
if ((newValue & SN_WIFISTATECONNECTED_BITMASK) == SN_WIFISTATECONNECTED_BITMASK)
{
if (!g_connected)
{
g_connected = true;
g_connecting = false;
MessageBox(hWnd, L"Connected!!", caption, MB_OK);
}
break;
}
if ((newValue & SN_WIFISTATECONNECTING_BITMASK) == SN_WIFISTATECONNECTING_BITMASK)
{
if (!g_connecting)
{
g_connecting = true;
g_connected =false;
MessageBox(hWnd, L"Connecting...", caption, MB_OK);
}
}
break;
}
[/b]
case WM_DESTROY:
CommandBar_Destroy(g_hWndMenuBar);
[B]
RegistryCloseNotification(g_hNotify);
RegistryCloseNotification(g_hNotify2);
[/B]
PostQuitMessage(0);
break;
case WM_ACTIVATE:
// Notify shell of our activate message
SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
break;
case WM_SETTINGCHANGE:
SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
// Create a Done button and size it.
SHINITDLGINFO shidi;
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
}
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hDlg, message);
return TRUE;
}
return (INT_PTR)FALSE;
}
Needed includes:
// TODO: reference additional headers your program requires here
#include <snapi.h>
#include <regext.h>
snapi.h
Thank you so much for your post. I just found snapi.h, I assume this is snapitest.h?
IT WORKS!
It works! You are my hero RStein. You are a god among men.
Great. ) Thanks for sharing the results.

How to prevent laggy scrolling ListView w ImageView-Items filled with cached images?

Hello community,
I've got a ListActivity in my app, which shows Views including TextViews, for showing artist, title and album information of some mp3-Files (queried by my cursor), and an ImageView, for showing an albumart => Similar to the Tracklist in the music app.
Here's the code for my custom SimpleCursorAdapter and it's binding to the ListView:
Code:
void setListAdapterOverride() {
String[] fromColumns = new String[] {
AudioColumns.ARTIST,
MediaColumns.TITLE,
AudioColumns.ALBUM,
AudioColumns.ALBUM_ID
};
int[] toColumns = new int[] {
R.id.tv_artist,
R.id.tv_title,
R.id.tv_album,
R.id.iv_albumArt
};
cursorAdapter = new customAdapter(getBaseContext(), R.layout.listviewitem, cursor, fromColumns, toColumns);
setListAdapter(cursorAdapter);
if (MyDebug.Log)
Log.d("Activity", "ListAdapter gesetzt");
}
class customAdapter extends SimpleCursorAdapter {
int layout;
Cursor cursor;
String[] from;
int[] to;
public customAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.layout = layout;
this.cursor = c;
this.from = from;
this.to = to;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.listviewitem, parent, false);
if (MyDebug.Log)
Log.d("Activity", "Inflate");
}
cursor.moveToPosition(position);
TextView artist = (TextView) row.findViewById(to[0]);
TextView title = (TextView) row.findViewById(to[1]);
TextView album = (TextView) row.findViewById(to[2]);
ImageView albumArt = (ImageView) row.findViewById(to[3]);
artist.setText(cursor.getString(cursor.getColumnIndex(from[0])));
title.setText(cursor.getString(cursor.getColumnIndex(from[1])));
album.setText(cursor.getString(cursor.getColumnIndex(from[2])));
Cursor albumArtCursor = contentResolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART }, MediaStore.Audio.Albums._ID + "='" + cursor.getInt(cursor.getColumnIndex(from[3])) + "'", null, null);
albumArtCursor.moveToFirst();
String albumArtUri = albumArtCursor.getString(albumArtCursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
if (albumArtUri == null) albumArtUri = "default";
if (!imageCache.containsKey(albumArtUri)) {
Bitmap albumArtBitmap;
if (!albumArtUri.equals("default")) {
Options opts = new Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(albumArtUri, opts);
Integer[] bitmapSize = new Integer[] { opts.outWidth, opts.outHeight };
Integer scaleFactor = 1;
while ((bitmapSize[0]/2 > 50) && (bitmapSize[1]/2 > 50)) {
scaleFactor++;
bitmapSize[0] /= 2;
bitmapSize[1] /= 2;
}
opts = new Options();
opts.inSampleSize = scaleFactor;
albumArtBitmap = BitmapFactory.decodeFile(albumArtUri, opts);
} else {
albumArtBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_mp_song_list);
}
imageCache.put(albumArtUri, albumArtBitmap);
}
albumArt.setImageBitmap(imageCache.get(albumArtUri));
return row;
}
}
imageCache is a Hashmap<String, Bitmap> for caching the Bitmaps, so they don't have to be decoded from file again when they had been cached before.
In a former version of the code, I didn't have the imageCache, so the albumarts were decoded from file everytime a new row has been added. That slowed down ListView-scrolling. By adding the imageCache scrolling in ListView doesn't lag that much as before, but it's lagging a bit sometimes.
Can anyone help me to further optimize my code to completely prevent lagging when I scroll the ListView?
Thanks regards ChemDroid

ImageView from url in listview

i created a java web service. it returns ArrayList type(text,image URL).
and my client side code i receive the by following code:
public class CustomeAdapter extends ArrayAdapter<RowItem> {
private List<RowItem> objects;
Context context;
private Bitmap bitmap;
Drawable d;
ViewHolder holder = null;
public CustomeAdapter(Context context, int listViewResourceId, List<RowItem> first) {
super(context, listViewResourceId, first);
this.context = context;
}
private class ViewHolder {
ImageView image;
TextView name,service,local;
}
@suppressLint("NewApi")
public View getView(int position, View convertView, ViewGroup parent){
//ViewHolder holder = null;
RowItem rowItem = getItem(position);
//final Bitmap bitmap = null;
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.image=(ImageView) convertView.findViewById(R.id.imageView1);
holder.name = (TextView) convertView.findViewById(R.id.item_textView1);
holder.service = (TextView) convertView.findViewById(R.id.item_textView2);
holder.local = (TextView) convertView.findViewById(R.id.item_textView3);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
holder.name.setText("Name:"+rowItem.getCustomerName());
holder.service.setText("Service:"+rowItem.getServiceName());
holder.local.setText("Locality:"+rowItem.getLocalityName());
String src="http://192.168.1.16:8080/"+rowItem.getImage();
try {
URL url = new URL(src);
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
holder.image.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
return convertView;
}
i am getting followimg error:
android.os.NetworkOnMainThreadException
can any one help me
I think there is a library that does this well, but can't remember it right now...
Check the library repo, and some of the apps that list libraries. Also, maybe Google will turn up something helpful.
Lazy list perhaps?
https://github.com/thest1/LazyList

Share Action Provider is unresponsive

i want to share a layout as an image. code listed below is working fine for the save action button but not for share action button. share action button remains unresponsive. i am unable to figure it out what is wrong.
Code:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.eid_card_final, menu);
MenuItem item = menu.findItem(R.id.action_share);
myshare = (ShareActionProvider)item.getActionProvider();
String sharestate = Environment.getExternalStorageState();
RelativeLayout rlShareLayout = (RelativeLayout)findViewById(R.id.relativeLayout);
Bitmap sharebitmap = Bitmap.createBitmap(rlShareLayout.getWidth(), rlShareLayout.getHeight(), Bitmap.Config.ARGB_8888);
Canvas sharecanvas = new Canvas(sharebitmap);
rlShareLayout.draw(sharecanvas);
try{
if (Environment.MEDIA_MOUNTED.equals(sharestate)) {
Random sharerand = new Random();
int sharerandnum = sharerand.nextInt(1000);
String sharefilename = sharerandnum + ".jpeg";
sharef = new File(getExternalFilesDir(null),sharefilename);
FileOutputStream shareout = new FileOutputStream(sharef);
boolean success = sharebitmap.compress(CompressFormat.PNG, 100, shareout);
}
} catch (Exception e) {
e.printStackTrace();
}
Intent shareintent = new Intent(Intent.ACTION_SEND);
shareintent.setType("image/*");
Uri shareuri = Uri.fromFile(sharef);
shareintent.putExtra(Intent.EXTRA_STREAM, shareuri.toString());
shareintent.setData(shareuri);
myshare.setShareIntent(shareintent);
return true;
}

Starting chronometer with if condition comparing strings

I have an android application that is receiving a string from an arduino via Bluetooth, names the string "data" and displays it by setting a TextView to the string "data". I want a chronometer to start when the incoming string matches a predefined string.
For example:
Code:
if data.equals(startChrono)){
chronometerLeft.setBase(SystemClock.elapsedRealtime());
chronometerLeft.start();
I actually have the arduino sending a "g" and am setting my string goL to be "g" but cannot get the chronometer to start when the g is received. My TextView shows the g. Code is below. I've tried several things and at a loss. Using same code for chronometer.start() with onClickListener with a button works great. I just need it to start the chronometer when i receive a specific string from the arduino.
Code:
beginListenForData();
// text.setText("Bluetooth Opened");
}
void beginListenForData() {
final Handler handler = new Handler();
final byte delimiter = 10; // This is the ASCII code for a newline
// character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted() && !stopWorker) {
try {
int bytesAvailable = mmInputStream.available();
if (bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for (int i = 0; i < bytesAvailable; i++) {
byte b = packetBytes[i];
if (b == delimiter) {
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0,
encodedBytes, 0,
encodedBytes.length);
final String data = new String(
encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable() {
public void run() {
text.setText(data);
String goL = "g";
String goR = "f";
chronometerLeft = (Chronometer)findViewById(R.id.chronometerLeft);
chronometerRight = (Chronometer)findViewById(R.id.chronometerRight);
if(data.equals(goL)){
chronometerLeft.setBase(SystemClock.elapsedRealtime());
chronometerLeft.start();
if(data.equals(goR))
chronometerRight.setBase(SystemClock.elapsedRealtime());
chronometerRight.start();
}
}
});
} else {
readBuffer[readBufferPosition++] = b;
}
}
}
} catch (IOException ex) {
stopWorker = true;
}
}
}
});
workerThread.start();
}
Sorry to bother, but in your while loop condition, what does the '!' before Thread do?

Categories

Resources