I have a custom control which is supposed to work like the Segmenttab controller in iOS.
It has 3 textviews and the layout is as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/groupofthree"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/background"
android:orientation="horizontal" >
<TextView
android:id="#+id/tv_1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#color/black"
android:gravity="center"
android:text="Retiree"
android:textColor="#color/whitetext"
android:textSize="15dp"
android:textStyle="normal" />
<TextView
android:id="#+id/tv_2"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#color/lightGrey"
android:gravity="center"
android:padding="3dp"
android:text="Under18/fulltime"
android:textColor="#color/whitetext"
android:textSize="15dp"
android:textStyle="normal" />
<TextView
android:id="#+id/tv_3"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#color/black"
android:gravity="center"
android:text="Others"
android:textColor="#color/whitetext"
android:textSize="15dp"
android:textStyle="normal" />
</LinearLayout>
The control looks like this:
public class SegmentedRadioGroup extends View{
private Context m_Context;
public TextView tv1;
public TextView tv2;
public TextView tv3;
int selectedIndex = 0;
public SegmentedRadioGroup(Context context, AttributeSet attrs) {
super(context, attrs);
m_Context = context;
}
public SegmentedRadioGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SegmentedRadioGroup(Context context) {
super(context);
// TODO Auto-generated constructor stub
m_Context = context;
LayoutInflater inflater = (LayoutInflater) m_Context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.threeradiobutton, null);
v.isInEditMode();
tv1 = (TextView) v.findViewById(R.id.tv_1);
tv2 = (TextView) v.findViewById(R.id.tv_2);
tv3 = (TextView) v.findViewById(R.id.tv_3);
tv1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
selectedIndex = 0;
tv1.setBackgroundColor(R.color.darkgrey);
tv2.setBackgroundColor(R.color.lightGrey);
tv3.setBackgroundColor(R.color.lightGrey);
}
});
tv2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
selectedIndex = 1;
tv1.setBackgroundColor(R.color.lightGrey);
tv2.setBackgroundColor(R.color.darkgrey);
tv3.setBackgroundColor(R.color.lightGrey);
}
});
tv3.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
selectedIndex = 2;
tv1.setBackgroundColor(R.color.lightGrey);
tv2.setBackgroundColor(R.color.lightGrey);
tv3.setBackgroundColor(R.color.darkgrey);
}
});
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
}
}
The activity in which i add this custom view to the layout is as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/background"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/widget1216"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/appspecific_menubar" >
<TextView
android:id="#+id/widget1222"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/transaction_accounts_topbar"
android:textColor="#color/whitetext"
android:textSize="18sp"
android:textStyle="bold" >
</TextView>
<ImageButton
android:id="#+id/home_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#null"
android:paddingBottom="5dip"
android:paddingLeft="10dip"
android:paddingTop="5dip"
android:src="#drawable/home" >
</ImageButton>
</RelativeLayout>
<LinearLayout
android:id="#+id/testLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />.
</LinearLayout>
And the activity looks like this. I have added the view into the layout using addview.
public class TransactionAccount extends Activity {
LinearLayout selector;
SegmentedRadioGroup sg_test;
LayoutInflater inflater;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.transactionaccount_main);
selector = (LinearLayout)findViewById(R.id.testLayout);
sg_test = new SegmentedRadioGroup(this);
selector.addView(sg_test);
// inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// selector = inflater.inflate(R.id., null);
// sg_test = new SegmentedRadioGroup(this);
// sg_test.tv1.setText("1");
// sg_test.tv2.setText("2");
// sg_test.tv3.setText("3");
// sg_test.tv1.setBackgroundColor(R.color.blacktext);
// sg_test.setVisibility(View.VISIBLE);
//
// Log.d("TransactionAccount", "onCreate++++++" + sg_test.tv1.getText());
// Log.d("TransactionAccount", "onCreate++++++" + sg_test.tv2.getText());
// Log.d("TransactionAccount", "onCreate++++++" + sg_test.tv3.getText());
}
}
But what i see on the screen is a blank screen.. and not the custom control which should show up. Kindly tell me where am i going wrong.
Thanks in advance.
First of all, you can't add child Views to a subclass of View because it doesn't have the addView method. Instead, you should extend ViewGroup or one of its subclasses(like LinearLayout, RelativeLayout etc).
After you do the above thing you can simple add the Views with:
View v = inflater.inflate(R.layout.threeradiobutton, this, true);
to actually add the inflated layout to the custom View.
Right now you don't see something on the screen because there isn't something to see, your custom View is empty.
Related
I'm attempting to implement a `setOnItemClickListener however it never seems to fire for some reason. The most common fix for this seems to be adding:
android:focusable="false"
android:focusableInTouchMode="false"
`
...however I still cannot seem to reach the setOnItemClickListener or fire the toast within it.
Any suggestions are appreciated.
Java Source:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preinstall_activity);
mContext = PreinstallActivity.this;
//fetchLinks(final UserData userData);
fetchLinks();
gridView = (GridView) findViewById(R.id.gridView2);
gridView.setAdapter(mAdapter);
// Implement On Item click listener
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
Toast.makeText(PreinstallActivity.this, mAdapter.getItem(position), Toast.LENGTH_SHORT).show();
}
});
}
XML Source:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".PreinstallActivity">
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:background="#color/primaryColor"
android:layout_width="match_parent"
android:paddingRight="10dp"
android:layout_height="wrap_content"
app:theme="#style/FreeMo.ToolBarStyle"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" >
<ImageView
android:id="#+id/action_bar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center|start"
android:background="#drawable/ic_toggle"
/>
<TextView
android:id="#+id/headline_text"
android:paddingLeft="20dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/rec_apps_title"
android:textColor="#color/edit_text"
android:textSize="#dimen/headline_text_size" />
<ImageView
android:id="#+id/user_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center|end"
android:background="#drawable/ic_menu"></ImageView>
</android.support.v7.widget.Toolbar>
<TextView
android:id="#+id/rec_apps_txt"
android:padding="12dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/rec_apps_txt"
android:textColor="#color/text_view"
android:textSize="#dimen/default_text_size" />
<GridView
android:layout_height="wrap_content"
android:id="#+id/gridView2"
android:layout_width="match_parent"
android:numColumns="auto_fit"
android:horizontalSpacing="10dp"
android:verticalSpacing="0dp">
</GridView>
</LinearLayout>
XML Source 2:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="5dp">
<ImageView
android:layout_height="64dp"
android:id="#+id/imageView1"
android:layout_width="64dp"
android:src="#drawable/ic_lock_handle"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
</ImageView>
<TextView
android:text="TextView"
android:layout_height="wrap_content"
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_below="#+id/imageView1"
android:layout_marginTop="0dp"
android:layout_centerHorizontal="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:textSize="10sp"
android:ellipsize="marquee"></TextView>
</RelativeLayout>
Java Source 2:
public class PreinstallAdapter extends BaseAdapter
{
private ArrayList<String> listCountry;
private ArrayList<String> listFlag;
private Activity activity;
public PreinstallAdapter(Activity activity, ArrayList<String> listCountry, ArrayList<String> listFlag) {
super();
this.listCountry = listCountry;
this.listFlag = listFlag;
this.activity = activity;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return listCountry.size();
}
#Override
public String getItem(int position) {
// TODO Auto-generated method stub
return listCountry.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public static class ViewHolder
{
public ImageView imgViewFlag;
public TextView txtViewTitle;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if(convertView==null)
{
view = new ViewHolder();
convertView = inflator.inflate(R.layout.preinstall_grid, null);
view.txtViewTitle = (TextView) convertView.findViewById(R.id.textView1);
view.imgViewFlag = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(view);
}
else
{
view = (ViewHolder) convertView.getTag();
}
view.txtViewTitle.setText(listCountry.get(position));
Picasso.with(activity).load(listFlag.get(position)).into(view.imgViewFlag);
// view.imgViewFlag.setImageResource(listFlag.get(position));
return convertView;
}
}
1.make sure that your Gridview have width and height.
2.add
android:focusable="false"
android:focusableInTouchMode="false"
to the LinearLayout . like this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:focusable="false"
android:focusableInTouchMode="false"
```````````````````````````````````>
Does anyone know why my seekbar listener is not picking up any data from the seekbar?? i have it all setup and working but it isnt updating the textviews, i think it has something to do with the popup window using a different activity layout to the activity it sits inside
public class Environment extends Activity implements OnSeekBarChangeListener
{
private ImageButton lockButton;
SeekBar bar;
TextView textProgress, textAction;
private PopupWindow pwindo;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.setup_environment);
lockButton = (ImageButton) findViewById(R.id.lock);
lockButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
initiatePopupWindow();
}
});
}
private void initiatePopupWindow() {
try {
LayoutInflater inflater = (LayoutInflater) Environment.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.annotation,
(ViewGroup) findViewById(R.id.popup_element));
pwindo = new PopupWindow(layout, 1000, 1200, true);
pwindo.showAtLocation(layout, Gravity.CENTER, 0, 0);
bar = (SeekBar)findViewById(R.id.seekBar1); // make seekbar object
bar.setOnSeekBarChangeListener(this);
textProgress = (TextView)findViewById(R.id.textViewProgress);
textAction = (TextView)findViewById(R.id.textViewAction);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
textProgress.setText("The value is: "+progress);
textAction.setText("changing");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
textAction.setText("starting to track touch");
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
seekBar.setSecondaryProgress(seekBar.getProgress());
textAction.setText("ended tracking touch");
}
}
Whenever i use the slider it should update with the int value 0-100 depending on where the slider is, it works if i create an activity and use it straight away, but when i put it in a popupwindow it doesnt do anything??
annotation.xml
<LinearLayout android:id="#+id/popup_element"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#65bea9"
android:orientation="vertical"
android:padding="10sp">
<EditText
android:layout_width="170dp"
android:layout_height="250dp"
android:id="#+id/editText2"
android:layout_gravity="center_horizontal"
android:background="#ffffff"
android:textColor="#000000"
android:hint="#string/hint_annotation"
android:scrollIndicators="right"
android:gravity="top"
android:inputType="textMultiLine"
android:textSize="8pt"/>
<TextView
android:id="#+id/textViewProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="progress displayed here"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_gravity="center"
android:textSize="6pt"></TextView>
<TextView
android:id="#+id/textViewAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textViewProgress"
android:layout_marginTop="2dp"
android:text="action displayed here"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_gravity="center"
android:textSize="6pt"></TextView>
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView1"
android:layout_marginTop="5dp"
android:max="100"
android:layout_gravity="center"></SeekBar>
<Button
android:id="#+id/btn_close_popup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/btn_submit"/>
setup environment xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/root"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activities.Environment">
<ImageButton
android:src="#mipmap/unlocked_syn"
android:layout_width="48dp"
android:layout_height="45dp"
android:id="#+id/lock"
android:layout_row="1"
android:layout_column="11" />
</LinearLayout>
Try this, you should be initializing your Seekbar etc by the views from the layout. Simply doing findViewById searches for the views in the activity
private void initiatePopupWindow() {
try {
LayoutInflater inflater = (LayoutInflater) Environment.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.annotation,
(ViewGroup) findViewById(R.id.popup_element));
pwindo = new PopupWindow(layout, 1000, 1200, true);
pwindo.showAtLocation(layout, Gravity.CENTER, 0, 0);
bar = (SeekBar)layout.findViewById(R.id.seekBar1); // make seekbar object
bar.setOnSeekBarChangeListener(this);
textProgress = (TextView)layout.findViewById(R.id.textViewProgress);
textAction = (TextView)layout.findViewById(R.id.textViewAction);
} catch (Exception e) {
e.printStackTrace();
}
}
I am getting a NullPointer Exception in custom ListView Adapter android application.
This is my custom class with a few variables and getter.
public class ViewClass {
String ItemName, Category, Amount, TotalAmount;
//get,set methods here
}
This is my Main Activity class.
public class ViewList extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ArrayList<ViewClass> details = new ArrayList<ViewClass>();
ViewClass[] v = new ViewClass[5];
for (int i = 0; i < 5; i++) {
v[i] = new ViewClass();
v[i].setItemName("Item Name");
v[i].setAmount("Rs 1111");
v[i].setCategory("cateGory");
v[i].setTotalAmount("aaaa");
details.add(v[i]);
}
ListView msgList = (ListView) findViewById(R.id.MessageList);
msgList.setAdapter(new CustomListAdapter(details, this));
// msgList.setOnItemClickListener(new OnItemClickListener() {
// public void onItemClick(AdapterView<?> a, View v, int position,
// long id) {
//
// String s = (String) ((TextView) v.findViewById(R.id.From))
// .getText();
// Toast.makeText(ViewList.this, s, Toast.LENGTH_SHORT).show();
// }
// });
}
}
This is the XML file for ListItem Layout, the name is list_item_trans
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvBGColor1"
android:layout_width="10dp"
android:layout_height="fill_parent"
android:background="#android:color/background_dark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/space" />
<TextView
android:id="#+id/tvItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/tvAmount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/space" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvBGColor2"
android:layout_width="10dp"
android:layout_height="fill_parent"
android:background="#android:color/background_dark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/space" />
<TextView
android:id="#+id/tvCat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp" />
<TextView
android:id="#+id/tvTotalAmount"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/space" />
</LinearLayout>
This is as the name suggests, the CustomListAdapter
public class CustomListAdapter extends BaseAdapter{
private ArrayList<ViewClass> _data;
Context _c;
CustomListAdapter(ArrayList<ViewClass> data, Context c) {
_data = data;
_c = c;
}
public int getCount() {
// TODO Auto-generated method stub
return _data.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return _data.get(position);
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) _c
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item_message, null);
}
TextView tvItemName = (TextView) v.findViewById(R.id.tvItem);
TextView tvCategory = (TextView) v.findViewById(R.id.tvCat);
TextView tvAmount = (TextView) v.findViewById(R.id.tvAmount);
TextView tvTotalAmount = (TextView) v.findViewById(R.id.tvTotalAmount);
ViewClass msg = _data.get(position);
tvItemName.setText(msg.ItemName);
tvCategory.setText("Subject: " + msg.Category);
tvAmount.setText(msg.Amount);
tvTotalAmount.setText(msg.TotalAmount);
return v;
}
}
I am getting the error on in the getView method of the CustomListAdapter
tvItemName.setText(msg.ItemName);
This is the XML file for ListItem Layout, the name is list_item_trans
So The xml layout name is list_item_trans.xml
v = vi.inflate(R.layout.list_item_message, null);
You are inflating list_item_message.xml but your layout name is list_item_trans.xml
Maybee the error is here ?
List item layout is list_item_trans, but you are inflating list_item_message.
Change this line:
v = vi.inflate(R.layout.list_item_message, null);
Into this:
v = vi.inflate(R.layout.list_item_trans, null);
NullPointer Exception in custom ListView Adapter is caused
because you are inflating list_item_message.xml instead of list_item_trans.xml and initializing textviews from list_item_trans.xml
so just change
v = vi.inflate(R.layout.list_item_message, null);
To this
v = vi.inflate(R.layout.list_item_trans, null);
I am a newbie of android programming. After some study of ListView and ArrayAdapter, i decided to write a simple demo program just for practicing.
I want to display my custom view style ListView, so I override ArrayAdapter's getView() function. I know that for preventing memory leak, parameter convertView should be checked, and only inflate new object when convertView is null. I Also make a AsyncTask to keep adding data into ArrayAdapter in background(in doInBackground), and keep notifyDataChanged to ListView(in onProgressUpdate() ).
Here is the problem: when I set MAX_ITEM=50 (which means how many data i will add in AsyncTask), everything works fine. But when I set MAX_ITEM=500, logcat shows error message: "Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views." and application shut down. Can anyone tell me where the problem is? The following is my source code "MyTest.java" and my layout xml file "main.xml" and "layout_row.xml", thanks for your watching and helping.
MyTest.Java:
public class MyTest extends Activity {
private static final String TAG="Tany";
private static final int MAX_ITEM = 50;
private MyArrayAdapter adapter;
private ListView listview;
private int addCounter = 0;
public class MyData implements Comparable<MyData>{
public String str1;
public String str2;
public String str3;
public MyData(String str1, String str2, String str3){
this.str1 = str1;
this.str2 = str2;
this.str3 = str3;
}
#Override
public int compareTo(MyData data) {
// TODO Auto-generated method stub
int result = this.str1.compareTo(data.str1);
return result;
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listview = (ListView)findViewById(R.id.listview);
adapter = new MyArrayAdapter(this, R.layout.layout_row);
//set adapter
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
Log.d(TAG, "position "+position+" is clicked");
Toast.makeText(parent.getContext(), adapter.getItem(position).str1+", "+adapter.getItem(position).str2, Toast.LENGTH_SHORT).show();
}
});
listview.setTextFilterEnabled(true);
}
public void onStart(){
super.onStart();
MyTask newTask = new MyTask();
newTask.execute();
}
public class MyTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
for(int i = addCounter; i<MAX_ITEM; i++)
{
adapter.add(new MyData("str1="+i,"str2="+i,"str3="+i));
addCounter++;
publishProgress();
}
return null;
}
#Override
protected void onProgressUpdate(Void... progress ){
adapter.notifyDataSetChanged();
}
#Override
protected void onPostExecute(Void result){
Log.d(TAG, "AsyncTask MyTask finsish its work");
}
}
public class MyArrayAdapter extends ArrayAdapter<MyData>{
public MyArrayAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
// TODO Auto-generated constructor stub
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
if(convertView == null){
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.layout_row, parent, false);
}else{
Log.d(TAG,"recycle view, pos="+position);
row = convertView;
}
TextView tv1 = (TextView) row.findViewById(R.id.textView1);
tv1.setText( ((MyData)getItem(position)).str1 );
TextView tv2 = (TextView) row.findViewById(R.id.textView2);
tv2.setText( ((MyData)getItem(position)).str2 );
TextView tv3 = (TextView) row.findViewById(R.id.textView3);
tv3.setText( ((MyData)getItem(position)).str3 );
return row;
}
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/vertical_container"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="#string/list_title_start"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TextView>
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</ListView>
<TextView
android:text="#string/list_title_end"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
layout_row.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="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/linearLayout1"
android:orientation="horizontal">
<ImageView
android:layout_height="wrap_content"
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:src="#drawable/ic_launcher">
</ImageView>
<TextView
android:text="TextView1"
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:textAppearance="?android:attr/textAppearanceLarge">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/linearLayout1"
android:orientation="horizontal">
<TextView
android:id="#+id/textView2"
android:text="TextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall">
</TextView>
<TextView
android:text="TextView"
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_marginLeft="6dip">
</TextView>
</LinearLayout>
</LinearLayout>
as Selvin rightly says You're modifying your Views from the method doInBackground which runs on another thread. In android this is forbidden, instead you should modify the views from the onPostExecute method also.
I am trying to add a custom header that isnt clickable but will have a checkbox that will "check all" checkboxes under it.
This is my List Fragment
public class AssesmentListFragment extends ListFragment {
private static String BUNDLE_KEY_APPLICATION = "LIST_ITEM";
FastAssesmentListAdapter adapter;
View listHeader;
public AssesmentListFragment() {}
public AssesmentListFragment(Data[] data) {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Data[] assestments = {new Data("Assesment ID","Name", "Date"), new Data("123456", "Assestment 2", "9/12/12"),
new Data("345672", "Assesment 3", "9/13/12"), new Data("566893", "Assesment 4", "9/14/12")};
//This is the part that makes the app crash
View header = getActivity().getLayoutInflater().inflate(R.layout.list_adapter_assesments, null);
ListView listView = getListView();
listView.addHeaderView(header);
adapter = new FastAssesmentListAdapter(getActivity(), assestments);
setListAdapter(adapter);
updateList(assestments);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
private void updateList(Data[] assestments) {
// NOTE: addAll is not being used to support pre-honeycomb devices
synchronized(adapter) {
adapter.clear();
adapter.addAll(assestments);
adapter.notifyDataSetChanged();
}
}
#Override
public void onListItemClick(ListView parentView, View selectedItemView, int position, long id) {
String model = (String) parentView.getItemAtPosition(position);
((FacilityActivity) getActivity()).onItemSelected(model);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//outState.putInt("curChoice", mCurCheckPosition);
}
}
This is the layout I am trying to use for header
<?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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="25dp"
android:paddingRight="10dp"
android:orientation="horizontal">
<TextView android:id="#+id/adapter_header_textview_column1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:textColor="#color/defaultTextColor"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="28sp"
android:text="Assesment ID" />
<TextView android:id="#+id/adapter_header_textview_column2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:textColor="#color/defaultTextColor"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="28sp"
android:text="Name" />
<TextView android:id="#+id/adapter_header_textview_column3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:textColor="#color/defaultTextColor"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="28sp"
android:text="Date"/>
<CheckBox
android:id="#+id/header_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:color="#color/defaultTextColor"
android:layout_weight=".5"
android:gravity="center" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="5dp"
android:background="#color/BPGreenColor" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Then this is the array adapter I am using:
public class FastAssesmentListAdapter extends ArrayAdapter<Data> {
private static int LAYOUT_ID = R.layout.list_adapter_with_checkbox_three_column;
private final Data[] assesments;
private final Context context;
LinearLayout listHeader;
static class ViewHolder {
protected TextView column1;
protected TextView column2;
protected TextView column3;
protected CheckBox checkbox;
}
public FastAssesmentListAdapter(Context context, Data[] assesments) {
super(context, LAYOUT_ID, assesments);
this.context = context;
this.assesments = assesments;
}
//ListFragment and array adapter will automatically call this over and over to auto populate the list
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final Data item = getItem(position);
// Formulate row view (create if it does not exist yet)
View view = convertView;
if(view == null) {
LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater();
view = inflater.inflate(LAYOUT_ID, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.column1 = (TextView) view.findViewById(R.id.adapter_textview_column1);
viewHolder.column2 = (TextView) view.findViewById(R.id.adapter_textview_column2);
viewHolder.column3 = (TextView) view.findViewById(R.id.adapter_textview_column3);
viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check_box);
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(), "Clicked",
Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getContext(), FacilityActivity.class);
getContext().startActivity(intent);
}
});
if(viewHolder.checkbox != null) {
viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(isChecked) {
item.setSelected(isChecked);
Toast.makeText(getContext(), "Checked",
Toast.LENGTH_SHORT).show();
}
}
});
}
view.setTag(viewHolder);
viewHolder.checkbox.setTag(position);
}
ViewHolder viewHolder = (ViewHolder) view.getTag();
viewHolder.checkbox.setTag(position);
viewHolder.column1.setText(item.getColumn1());
viewHolder.column2.setText(item.getColumn2());
viewHolder.column3.setText(item.getColumn3());
viewHolder.checkbox.setChecked(item.isSelected());
return view;
}
}
on a side note, the onlistitemclicked in the fragment doesnt work, i have to set a listener in the adapter and then it works. any ideas on that? but mainly I need to figure out how to use a custom header and custom rows in the list view. Here is the layout for the rows
<?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="wrap_content"
android:paddingLeft="25dp"
android:paddingRight="10dp"
android:orientation="horizontal">
<TextView android:id="#+id/adapter_textview_column1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="25sp" />
<TextView android:id="#+id/adapter_textview_column2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="25sp" />
<TextView android:id="#+id/adapter_textview_column3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="25sp" />
<CheckBox
android:id="#+id/check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:gravity="center" />
</LinearLayout>