I'm a noob to android development and I am having trouble instantiating an ImageView within a ViewPager. My ViewPager has 7 pages and all of them have ImageViews. However, only the ImageView on the first page instantiates and doesn't return null when called. I checked repeatedly to be certain that each viewpager page is referencing the correct xml and am certain that each corresponding xml has the appropriate ImageView. Any help is greatly appreciated.
MY CODE
Working viewpager page.
case 0:
resId = (R.layout.reference_layout);
view = inflater.inflate(resId, null);
herb_ListView = (IndexableListView)view.findViewById(R.id.herbList);
herbsListresource = res.getStringArray(R.array.herblist);
herbsItems = new ArrayList<String>();
Collections.addAll(herbsItems, herbsListresource);
Collections.sort(herbsItems);
ArrayAdapter<String> herbs_adapter = new CustomListAdapter(ReferenceActivity.this, R.layout.list_item_herbs);
for (int i=0; i<herbsItems.size();i++)
herbs_adapter.add(herbsItems.get(i));
herb_ListView.setAdapter(herbs_adapter);
herb_ListView.setFastScrollEnabled(true);
herb_ListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
View toolbar = view.findViewById(R.id.toolbar);
String herb_info = herb_ListView.getItemAtPosition(position).toString() + "_info";
String new_herb_info = herb_info.replaceAll("\\s+", "").replace("'", "").replace(".", "");
Log.e("herb_info result", new_herb_info);
String herb_pic = herb_ListView.getItemAtPosition(position).toString().toLowerCase() + "_picture";
String new_herb_pic = herb_pic.replaceAll("\\s+", "").replace("'", "").replace(".", "");
Log.e("herb_pic result", new_herb_pic);
try{
((ImageView)view.findViewById(R.id.herb_image)).setImageResource((ReferenceActivity.this.getResources().getIdentifier(new_herb_pic, "drawable", ReferenceActivity.this.getApplicationInfo().packageName)));
((TextView)view.findViewById(R.id.herb_description)).setText((ReferenceActivity.this.getResources().getIdentifier(new_herb_info, "string", ReferenceActivity.this.getApplicationInfo().packageName)));
}catch(Exception e){
Log.e("Herb Info Error", "Error loading Herb Info >> " + e.getMessage() + " //" + e.toString());
}
//Setting Arrows
if(((ImageView)view.findViewById(R.id.chevron)).getTag()=="down"||((ImageView)view.findViewById(R.id.chevron)).getTag()==null){
((ImageView)view.findViewById(R.id.chevron)).setImageResource(R.drawable.chevron_white);
((ImageView)view.findViewById(R.id.chevron)).setTag("up");
}else{
((ImageView)view.findViewById(R.id.chevron)).setImageResource(R.drawable.chevron_white_down);
((ImageView)view.findViewById(R.id.chevron)).setTag("down");
}
// Creating the expand animation for the item
ExpandAnimation expandAni = new ExpandAnimation(toolbar, 500);
// Start the animation on the toolbar
toolbar.startAnimation(expandAni);
}
});
((ViewPager) collection).addView(view, 0);
return view;
Non-working viewpager page.
case 4:
resId = (R.layout.reference_layout);
view = inflater.inflate(resId, null);
crystals_ListView = (IndexableListView)view.findViewById(R.id.herbList);
crystalsListresource = res.getStringArray(R.array.crystallist);
crystalsItems = new ArrayList<String>();
Collections.addAll(crystalsItems, crystalsListresource);
Collections.sort(crystalsItems);
ArrayAdapter<String> crystals_adapter = new CustomListAdapter(ReferenceActivity.this, R.layout.list_item_crystals);
for (int i=0; i<crystalsItems.size();i++)
crystals_adapter.add(crystalsItems.get(i));
crystals_ListView.setAdapter(crystals_adapter);
crystals_ListView.setFastScrollEnabled(true);
crystals_ListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
View toolbar = view.findViewById(R.id.crystal_toolbar);
String crystal_sign = crystals_ListView.getItemAtPosition(position).toString() + "_definition";
String new_crystal_sign = crystal_sign.replaceAll("\\s+", "").replace("'", "").replace(".", "").replace("(", "").replace(")", "");
Log.e("crystal_sign result", new_crystal_sign);
String crystal_mode = crystals_ListView.getItemAtPosition(position).toString() + "_optimumday";
String new_crystal_mode = crystal_mode.replaceAll("\\s+", "").replace("'", "").replace(".", "").replace("(", "").replace(")", "");
Log.e("crystal_mode_result", crystal_mode);
String crystal_usage = crystals_ListView.getItemAtPosition(position).toString() + "_usage";
String new_crystal_usage = crystal_usage.replaceAll("\\s+", "").replace("'", "").replace(".", "").replace("(", "").replace(")", "");
Log.e("crystal_usage_result", new_crystal_usage);
try{
TextView crystalSign = (TextView)view.findViewById(R.id.crystal_sign);
TextView crystalMode = (TextView)view.findViewById(R.id.crystal_mode);
TextView crystalUsage = (TextView)view.findViewById(R.id.crystal_usage);
crystalSign.setText("Sign: " +(ReferenceActivity.this.getResources().getIdentifier(new_crystal_sign, "string", ReferenceActivity.this.getApplicationInfo().packageName)));
crystalMode.setText("Mode: " +(ReferenceActivity.this.getResources().getIdentifier(new_crystal_mode, "string", ReferenceActivity.this.getApplicationInfo().packageName)));
crystalUsage.setText("Usage: " +(ReferenceActivity.this.getResources().getIdentifier(new_crystal_usage, "string", ReferenceActivity.this.getApplicationInfo().packageName)));
}catch(Exception e){
Log.e("Crystal Info Error", "Error loading Crystal Info >> " + e.getMessage() + " //" + e.toString());
}
//Setting Arrows
ImageView chevron = (ImageView)view.findViewById(R.id.crystal_chevron);
if(chevron.getTag()=="down"||chevron.getTag()==null){ //NULLPOINTER THROWN HERE.
chevron.setImageResource(R.drawable.chevron_white);
chevron.setTag("up");
}else{
chevron.setImageResource(R.drawable.chevron_white_down);
chevron.setTag("down");
}
// Creating the expand animation for the item
ExpandAnimation expandAni = new ExpandAnimation(toolbar, 500);
// Start the animation on the toolbar
toolbar.startAnimation(expandAni);
}
});
((ViewPager) collection).addView(view, 0);
return view;
Non-working viewpager 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" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/crystal_title"
android:layout_width="275dp"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="20dip"
android:textSize="20dp" />
<ImageView
android:id="#+id/crystal_chevron"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="30dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:src="#drawable/chevron_white_down"
android:layout_gravity="right"
android:padding="20dip"/>
</LinearLayout>
<!-- *********************** -->
<!-- *** TOOLBAR LAYOUT **** -->
<!-- *********************** -->
<LinearLayout
android:id="#+id/crystal_toolbar"
android:layout_width="fill_parent"
android:layout_height="150dip"
android:layout_marginBottom="-50dip"
android:orientation="vertical"
android:visibility="gone" >
<TextView
android:id="#+id/crystal_sign"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="2dip"
android:text="No information available" />
<TextView
android:id="#+id/crystal_mode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="2dip"
android:text="No information available" />
<TextView
android:id="#+id/crystal_usage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="2dip"
android:text="No information available" />
</LinearLayout>
I don't have any hard proof for this but my thoughts on why only views within the first fragment in the ViewPager can be found is because the others do not "exist." Sure, they exist in XML, but I don't know that all layouts are inflated and matinatined once the Fragments are added such that you can update them directly if the UI is not visible (or at all).
I also do not think you can use findViewById to reach a view within a Fragment hosted by your ViewPager. findViewById only looks within the content view supplied - i.e. the layout for that activity - or a specific layout you supply to it - e.g. if you inflate a particular layout, like that of a list item, and then call findViewById on that to find a view inside, like a TextView. You should not be able to just call findViewById on a view for some Fragment and change it.
As to fixing the problem. Your views should be initialized within the fragments themselves. If you're tring to update the view in the fragment based on something that occurs in your FragmentActivity then I would try this
(1) Keep a reference to the fragments you are adding to your ViewPager
Private whateverFragment f1
//initialize onCreate
f1= new WhateverFragment();
(2) Declare a public method in that fragment you can use to update the view you want. Note the view is initialized within the fragment not the host activity.
public updateTextView(String idk){
TextView message = (TextView)getActivity().findViewById(R.id.message);
message.setText(idk);
}
(3) if you want to know the update is complete, or commuicate back from the fragment to the fragment activity, just use an interface. The easiest way to do it is to declare an interface in your fragment, implement that interface in the host activity, and initialize the interface within the fragments onAttach method. This way you can callback between the fragment and its host activity.
Using this approach you can pretty much control everything within your fragment from the activity containing the view pager
Related
I have a ListView in one of my activities that I have bound to an ArrayList using a custom ArrayAdapter. I have set an OnItemClickListener to the ListView which should call a method that starts another activity. However, I find that when I click on the ListView items, it only sometimes works. Sometimes it will start the activity as it should; other times it seems to detect the click (the ripple effect appears on the list item) but does nothing; other times it doesn't even appear to detect the click (the ripple effect doesn't appear).
I've tried all the usual suggestions that I've come across: blocking descendants on the parent view item, setting clickable and focusable to false on all the components of the item views, setting isEnabled to return true in the custom adapter, etc, but the behavior remains the same. Any help appreciated. Here is the relevant code:
Activity containing the ListView:
public class ViewCollectionActivity extends AppCompatActivity {
private final String className = this.getClass().getSimpleName();
private CollectionHandler collectionHandler;
private Context context;
private ArrayList<Game> displayedCollection;
private GameCollectionAdapter collectionAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_collection);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
context = this;
collectionHandler = CollectionHandler.getInstance(this);
TextView view = null;
if (collectionHandler.getDisplayedCollection().size() > 0) {
view = (TextView) findViewById(R.id.no_items_textview);
view.setVisibility(View.GONE);
}
String currentDate = collectionHandler.getDateLastSynchronised();
view = (TextView) findViewById(R.id.last_updated_textview);
view.setText("Last synchronised: " + currentDate + " Total games: " + String.valueOf(collectionHandler.getDisplayedCollection().size()));
collectionAdapter = collectionHandler.getCollectionAdapter();
ListView listView = (ListView) findViewById(R.id.collection_list_view);
listView.setAdapter(collectionAdapter);
AdapterView.OnItemClickListener collectionItemClickListener = new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
launchGameDetailsActivity(position);
}
};
listView.setOnItemClickListener(collectionItemClickListener);
}
public void launchGameDetailsActivity(int position){
Log.d(className,"Starting lauchGameDetailsActivity method");
collectionHandler.setSelectedGame(position);
Intent intent = new Intent(this,ViewGameDetailsActivity.class);
startActivity(intent);
Log.d(className, "Ending lauchGameDetailsActivity method");
}
The XML for the activity:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.bleachedlizard.ludome.viewcollection.ViewCollectionActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Synchronise Collection"
android:onClick="synchroniseCollection"/>
<TextView
android:id="#+id/last_updated_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Last synchronised: "
android:textAlignment="center"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Display Collection"
android:visibility="gone"
android:onClick="displayCollection"/>
<ListView
android:id="#+id/collection_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
<TextView
android:id="#+id/no_items_textview"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="You have no items in your collection."
android:textAlignment="center"
android:textSize="20sp"/>
</LinearLayout>
The XML for the item views:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/collection_item_layout"
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal"
android:clickable="false"
android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:focusableInTouchMode="false">
<ImageView
android:id="#+id/collection_item_image"
android:layout_width="75dp"
android:layout_height="75dp"
android:src="#drawable/testimage"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
/>
<TextView
android:id="#+id/collection_item_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:padding="16dp"
android:singleLine="false"
android:textColor="#android:color/darker_gray"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:textIsSelectable="false"/>
<TextView
android:id="#+id/collection_item_plays"
android:layout_width="100dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:padding="8dp"
android:textColor="#android:color/darker_gray"
android:text="Plays: 0"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:textIsSelectable="false"/>
</LinearLayout>
The code for the custom adapter:
public class GameCollectionAdapter extends ArrayAdapter<Game> {
private ArrayList<Game> collection;
public GameCollectionAdapter(Context context, int resource, ArrayList<Game> collection){
super(context, resource, collection);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout gameView = (LinearLayout) convertView;
LayoutInflater mInflater = LayoutInflater.from(getContext());
if (gameView == null) {
gameView = (LinearLayout) mInflater.inflate(R.layout.collection_item_view, null);
}
//Game game = collection.get(position);
Game game = super.getItem(position);
if (game != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView gameTitle = (TextView) gameView.findViewById(R.id.collection_item_name);
TextView numOfPlays = (TextView) gameView.findViewById(R.id.collection_item_plays);
ImageView thumbnail = (ImageView) gameView.findViewById(R.id.collection_item_image);
// check to see if each individual textview is null.
// if not, assign some text!
if (gameTitle != null){
gameTitle.setText(game.getTitle());
}
if (numOfPlays != null){
numOfPlays.setText("Plays: " + String.valueOf(game.getNumOfPlays()));
}
if (thumbnail != null){
thumbnail.setImageBitmap(game.getThumbnail());
}
}
// the view must be returned to our activity
return gameView;
}
#Override
public boolean isEnabled(int position) {
return true;
}
}
I discovered what was causing the problem: the way I had set up the array that backed the ListView meant that it was downloading and storing the Bitmaps for every element in the array all the time. Once I changed the implementation so that it only downloaded the images as the ListView required them, then that seemed to improve performance and the onClickListener started to work fine.
The implementation I used was the exact same one shown here:
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
I think the issue is due to the position of the item selection whenever you click you have an list position which is passed to your method launchGameDetailActivity(int position) check with log or toast on item click what all the position you are getting do the needful.
Here is my code try this like this if it helps.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(RecipeClass.this, "Position is" + position, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(RecipeClass.this, RecipeIngredients.class)
intent.putExtra("position", position);
startActivity(intent);
}
Check your arraylist value also whether they are not null.
How can I add a Total TextView inside ListView, as well as a Save Button under the ListView, dynamically?
Total is to be displayed similar to the following image. (note: not my data representation)
Activity A (Code Snippet)
long as=0; // for total
long bs=0;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
// receive from B
switch (requestCode)
{
case 0:
result = data.getStringExtra("text"); // holds value (34,24)
name = data.getStringExtra("a"); // Project
as = as+Long.parseLong(result); // For total amount
Text = " " + name + " " + "RM" + result + ""; // display in listView
if (mClickedPosition == -1) {
//add new list
m_listItems.add(Text);
m_listBitmapItems.add(Global.img);
} else {
// edit listView value and image
m_listItems.set(mClickedPosition, Text);
m_listBitmapItems.set(mClickedPosition, Global.img);
}
adapter.notifyDataSetChanged();
listV.setAdapter(adapter);
break;
case 1: // Another name
result = data.getStringExtra("text");
name = data.getStringExtra("a");
description = data.getStringExtra("c");
bs = bs + Long.parseLong(result);
Log.d("FIRST", "result:" + result);
Text = " " + name + " " + "RM" + result + "";
if (mClickedPosition == -1)
{
m_listItems.add(Text);
} else {
m_listItems.set(mClickedPosition, Text);
}
adapter.notifyDataSetChanged();
listV.setAdapter(adapter);
break;
}
}
long samount = as + bs;
Toast.makeText(getActivity(), samount + "", Toast.LENGTH_LONG).show();
}
Activity A (Rendered Output)
Here I would like to add a Total TextView with value 58 (output as RM58), as well as a Save Button.
I am using the following xml files.
a.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:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="#string/text"
android:textSize="20sp" />
<ListView android:id="#+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
claims.xml (inside the listView)
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout 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/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView android:id="#+id/imageView4"
android:layout_width="101dp"
android:layout_height="50dp" />
</AbsoluteLayout>
Thanks.
Add the following footer.xml file to res/layout http://developer.android.com/reference/android/widget/ListView.html
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent
android:orientation="vertical" >
// Format as you please
<TextView
android:id="#+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Total" />
</LinearLayout>
In your activity create and initialise the following variables.
LayoutInflater inflater = getLayoutInflater();
ViewGroup footer = (ViewGroup) inflater.inflate(R.layout.footer, listView,
false);
// You can add this when an item is added and remove it if the list is empty.
listView.addFooterView(footer, null, false);
tv = (TextView)footer.findViewById(R.id.tv);
// Update the text.
tv.append("t/"+ results.toString());
As mentioned in the comments, you can either use long total as a static class member and update it with the results value total+=results; taking care to reset the value to zero or decrement it if an item is removed from the list.
The other way is to loop through the items in your list, parsing the items to the object and getting the particular value of type long from each object and summing them as you go.
As you are now able to dynamically add your button, I'll add briefly for other users browsing, set the buttons visibility to GONE, so that the element does not displace the layout when it is not visible, HIDDEN makes the element not visible, but the space taken by the element affects the layout (and sometimes this is useful). Then the button visibility is dynamically changed to VISIBLE when an item is added to the list, and back to GONE when the list is cleared.
<Button
android:id="#+id/btn"
android:text="button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
http://developer.android.com/reference/android/transition/Visibility.html
Does anyone know how I could create a for loop(?) for my imageView and textView without adding them in my XML file? I'm not sure if it is possible too..so I would appreciate if someone could help me in this.
For your info, I would like to grab data from another activity. eg. If the user click the add to Favourite button, I would display another imageView & textView in this activity of the clothes image and name. The activity will also display the previous items that is added to the page.
XML file:
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/name"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="a" />
</LinearLayout>
Inside my onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_favourite);
editButton = (Button)findViewById(R.id.edit);
image = (ImageView)findViewById(R.id.image);
name = (TextView)findViewById(R.id.name);
}
Thank you.
I think what you are going to want to do is in your layout have a ListView, and then you create something that implements ListAdapter (ArrayAdapter is a good choice). In your adapter you can reuse one xml file that would contain your ImageView and TextView.
There are a lot of good tutorials out there on it, Googling "ListView Adapter" will get you pretty far. Here's a good one: http://www.vogella.com/articles/AndroidListView/article.html
Yours is a pretty simple case, so you can use an ArrayAdapter like this:
Activity:
public class MainActivity extends Activity {
private ArrayAdapter<String> listAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<String>()) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (convertView == null)
{
v = super.getView(position, convertView, parent);
}
String text = getItem(position);
TextView textview = ((TextView) v.findViewById(android.R.id.text1));
textview.setText(text);
// Now you can set an image by calling
// textview.setCompoundDrawablesWithIntrinsicBounds(...);
return v;
}
};
((ListView) findViewById(R.id.listView)).setAdapter(listAdapter);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
private int i = 0;
#Override
public void onClick(View view) {
listAdapter.add("item number: " + (++i));
listAdapter.notifyDataSetChanged();
}
});
}
}
Layout activity_main:
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
tools:listitem="#layout/listview_row"
android:layout_above="#+id/button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
Alternative:
If you are bent on not using a ListView or for whatever reason you can't use a list view, you can always inflate a layout and add it to another layout in your app. The code below would then replace the code above in the button's on click:
View row = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, null); /* null here means it's not attaching/populating a view you already have */
((TextView) row.findViewById(android.R.id.text1)).setText("item number: " + (++i));
((ViewGroup) findViewById(R.id.linearlayout)).addView(row);
findViewById(R.id.linearlayout).invalidate();
Using a ListView here is the right way to go, so this is kind of a last resort.
I'm not sure of what you want, maybe this?
for (int i = 1; i <= 20; i++) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
Button btn = new Button(this);
btn.setId(i);
final int id_ = btn.getId();
btn.setText("button " + id_);
btn.setBackgroundColor(Color.rgb(70, 80, 90));
linear.addView(btn, params);
btn1 = ((Button) findViewById(id_));
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(view.getContext(),
"Button clicked index = " + id_, Toast.LENGTH_SHORT)
.show();
}
});
}
Im trying to display drawables from packages installed on the android device example: "com.android.browser" to show an icon for the application.
I have setup an sherlocklistfragment with this layout
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/appName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/numOpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Then i use a hashmap to handle the data for the simpleAdapter
Sherlocklistfragment
public class List_fragment extends SherlockListFragment {
private PackageManager pk;
String[] apps = new String[] {
"Browser",
"Email",
"Facebook",
"Clock",
"Map",
"Calendar",
"Settings",
"Media player",
"Google play",
"testapp"
};
String[] period = new String[]{
"54",
"23",
"42",
"23",
"14",
"23",
"23",
"1",
"10",
"12"
};
public final static String TABLE_LOGS = "logs";
public final static String ID_COL = "_id";
public final static String DATE_COL = "date";
public final static String PACKAGE_COL = "package";
public final static String LAT_COL = "lat";
public final static String LNG_COL = "lng";
public final static String DUR_COL = "duration";
View view;
private OnItemClickListener mOnItemClickListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
List<HashMap<String,Object>> aList = new ArrayList<HashMap<String,Object>>();
pk = getSherlockActivity().getPackageManager();
Drawable drawable = null;
for(int i=0;i<10;i++){
HashMap<String, Object> hm = new HashMap<String,Object>();
hm.put("app", "" + apps[i]);
hm.put("per", period[i] + " seconds");
try {
drawable = pk.getApplicationIcon("com.android.browser");
//hm.put("image", drawable);
hm.put("image", R.drawable.down_arrow);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
aList.add(hm);
}
Log.d("DRAWABLE", " "+ drawable);
SimpleAdapter listAdapter = new SimpleAdapter(inflater.getContext(), aList,
R.layout.list_layout, new String[] {"image", "app", "per"}, new int[] {R.id.imageView, R.id.appName, R.id.numOpen});
//listAdapter.setViewBinder(mViewBinder);
setListAdapter(listAdapter);
Log.d("String " , " " + aList);
return super.onCreateView(inflater, container, savedInstanceState);
}
private final SimpleAdapter.ViewBinder mViewBinder = new SimpleAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Object data,
String textRepresentation) {
// TODO Auto-generated method stub
if(view instanceof ImageView){
((ImageView) view).setImageDrawable((Drawable) data);
}
return false;
}
};
}
EDIT: code
This shows the text for appName and the arrow icon on imageview, BUT it doenst show the drawable i have inserted in the simple adapter?
See this commented line:
//hm.put("image", drawable);
What am I doing wrong?
There are may ways to do that, but first of all, your fragment layout should have a ListView.
Screen Layout
ListFragment has a default layout that consists of a single list view. However, if you desire, you can customize the fragment layout by returning your own view hierarchy from onCreateView(LayoutInflater, ViewGroup, Bundle). To do this, your view hierarchy must contain a ListView object with the id "#android:id/list" (or list if it's in code)
Optionally, your view hierarchy can contain another view object of any type to display when the list view is empty. This "empty list" notifier must have an id "android:empty". Note that when an empty view is present, the list view will be hidden when there is no data to display. Android Documentation
As you are using a SherlockListFragment your layout must have ListView with a predefined android:id=#android:id/list
Row Layout
You can specify the layout of individual rows in the list. You do this by specifying a layout resource in the ListAdapter object hosted by the fragment (the ListAdapter binds the ListView to the data; more on this later).
A ListAdapter constructor takes a parameter that specifies a layout resource for each row. It also has two additional parameters that let you specify which data field to associate with which object in the row layout resource. These two parameters are typically parallel arrays. Android Documentation
You must define the row layout using a separate xml or build it dynamic for
each row. This first option is more commom.
As #Johannes said for SimpleAdapter you must have only TextView. Here you can se a example with custom layout using only TextView. So you have to use/extends another ListAdapter, for instance a ArrayAdapter or even a BaseAdapter.
The most important thing about it is the method getView, which is the method responsible to
return the view which will be put on each line of your ListView. In this method, you will must inflate you row layout and fill it.
This link show a complex custom layout example using BaseAdapter. You can take a look at this link that show basic custom layout is is better to understand what exactly you have to do.
From http://developer.android.com/reference/android/widget/SimpleAdapter.html#SimpleAdapter
For Parameter to (the last one, your imageView1 and textView1:
The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the
values of the first N columns in the from parameter.
I have solved my problem now. Thanks for the help.
With the use of http://android-er.blogspot.dk/2012/03/display-video-thumbnail-on-listfragment.html I have created a row.xml layout file and a custom cursor adapter as follows:
Cursor adapter
public class MyCursorAdapter extends SimpleCursorAdapter{
public MyCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to){
super(context, layout, c, from, to);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater = getSherlockActivity().getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
TextView text1 = (TextView)row.findViewById(R.id.text1);
TextView text2 = (TextView)row.findViewById(R.id.text2);
ImageView image1 = (ImageView)row.findViewById(R.id.image1);
Cursor cursor = adapter.getCursor();
cursor.moveToPosition(position);
try {
info = pk.getApplicationInfo(cursor.getString(cursor.getColumnIndex(PACKAGE_COL)), 0);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String title = (String) pk.getApplicationLabel(info);
text1.setText(title);
String duration = cursor.getString(cursor.getColumnIndex(DUR_COL));
text2.setText("App open for " + duration + " seconds");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Drawable d = info.loadIcon(pk);
image1.setImageDrawable(d);
return row;
}
}
Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/image1"
android:layout_width="75dp"
android:layout_height="75dp"
android:src="#drawable/ic_launcher"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/text1"
android:textSize="22dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/text2"
android:textSize="18dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
<ImageView
android:id="#+id/image2"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="#drawable/arrow"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
I have a custom dialog with the format of Header + listview + footer. The corresponding code is as follows: (I don't mind to share the code but it is over 800 lines) ...
/* Setup dialog layout */
View header = (View)getLayoutInflater().inflate(R.layout.stockcountheader, null);
View footer = (View)getLayoutInflater().inflate(R.layout.stockcountfooter, null);
final Dialog listDialog;
listDialog = new Dialog(this, android.R.style.Theme_Dialog);
listDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
LayoutInflater li = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = li.inflate(R.layout.dialog, null, false);
listDialog.setContentView(v);
listDialog.setCancelable(true);
final AdditemAdapter adapter = new AdditemAdapter(this, R.layout.additemrow, updateitems);
final ListView filterrow = (ListView) listDialog.findViewById(R.id.dialoglist);
filterrow.addHeaderView(header);
filterrow.addFooterView(footer);
filterrow.setAdapter(adapter);
i = adapter.getCount();
listDialog.show();
In the header, I have a radiobutton and intend to control the visibility of the listview row. So, I have the following code: ...
radiostockresGroup = (RadioGroup)listDialog.findViewById(R.id.radiostockres);
radiostockresButton = (RadioButton) radiostockresGroup.findViewById(radiostockresGroup.getCheckedRadioButtonId());
radiostockresGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup radiostockresGroup, int checkedId) {
radiostockresButton = (RadioButton) radiostockresGroup.findViewById(checkedId);
switch(checkedId) {
case R.id.radioresno:
listDialog.findViewById(R.id.tblayout2).setVisibility(View.INVISIBLE);
break;
case R.id.radioresyes:
listDialog.findViewById(R.layout.tblayout2).setVisibility(View.VISIBLE);
break;
}
}
});
However, it give me the java null pointer error in the "listDialog.findViewById(R.id.tblayout2).setVisibility(View.INVISIBLE); " line. The xml for the listview and the dialog is as follows:
stocktakerow.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableLayout android:id="#+id/tblayout2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0"
android:stretchColumns="*">
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/txtfieldname"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_span="3"
android:gravity="top" />
<EditText android:id="#+id/txtinput"
android:layout_toRightOf="#+id/txtfieldname"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_span="3"
android:gravity="top" />
</TableRow>
</TableLayout>
</RelativeLayout>
I try to use " filterrow.findViewById(R.id.tblayout2).setVisibility(View.INVISIBLE);" and still got the same null pointer.
Please kindly give me a hand, thanks a lot in advance!
Kelvin
If you look at your code, you will notice:
final ListView filterrow = (ListView) listDialog.findViewById(R.id.dialoglist);
listDialog.findViewById(R.id.tblayout2).setVisibility(View.INVISIBLE);
Essentially, you are saying that R.id.tblayout2 is a member of the same thing as R.id.dialoglist. I don't think they are in this case.
Not seeing what your class extends, I can only suppose that this should work. If it doesn't, can you please post the class definitions? Just the line like public class MainActivity extends Activity { will do for both classes.
findViewById(R.id.tblayout2).setVisibility(View.INVISIBLE);