I am making an application, and I want to change an image inside some layout from another layout. Is that possible? Here is the case, the details activity contains spinner which has the items important and draft, and there is a save button which saves data in db. The main activity has a list view, each row consists of image view and text view. The xml file of the details activity is not the same as the xml file of the row layout which contains the image view. The image in the image view should change based on the value of the spinner in the saved note. I understand that the value of spinner can be passed by intents, and based on that we can set the image. But I am getting error due to referencing the id of the image view which is not in the xml file of the main activity. I am using the row xml only as argument in the loader, which is in the main activity, where the main activity xml file is different from the row xml file. In other words, there is no activity that uses row xml file as its layout, it is only used as a parameter in the loader. So, is changing the image possible in this case?
Here is the code I used in the details fragment in order to send the spinner value to a fragment in another activity:
if (isUpdateQuery) {
long id = getActivity().getIntent().getLongExtra("id", 0);
int updated = getActivity().getContentResolver().update(NotesContract.NotesTable.buildUriWithId(id), values, null, null);
Intent intent = new Intent(getActivity(), NotesList.class);
intent.putExtra("category", category);
startActivity(intent);
}//en inner if
And, this is the code I used in the fragment to get the spinner value and update the image:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View temp = inflater.inflate(R.layout.notes_row, container, false);
ImageView imageView = (ImageView) temp.findViewById(R.id.icon);
if (getActivity().getIntent().getStringExtra("category")!=null && getActivity().getIntent().getStringExtra("category").equalsIgnoreCase("important")){
imageView.setImageResource(R.drawable.staricon);
}
mSimpleCursorAdapter=new SimpleCursorAdapter(getActivity(),R.layout.notes_row,null, from, to,0);
View rootView = inflater.inflate(R.layout.fragment_todo_list, container, false);
getLoaderManager().initLoader(LOADER_ID, null, this); //once this is done onCreateLoader will be called.
final ListView listView = (ListView) rootView.findViewById(R.id.notes_list); //findViewById must be called using the rootView because we are inside a fragment.
if(mSimpleCursorAdapter.getCount()==0) {
TextView text= (TextView) rootView.findViewById(R.id.empty_list);
text.setVisibility(View.VISIBLE);
}
if (getActivity().findViewById (R.id.fragment_container)!=null){
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);}//end if.
listView.setAdapter(mSimpleCursorAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Cursor cursor = mSimpleCursorAdapter.getCursor();
if (cursor != null && cursor.moveToPosition(position)) {
String category= cursor.getString(1);
String summary= cursor.getString(2);
String description=cursor.getString(3);
long id= cursor.getLong(cursor.getColumnIndex(NotesContract.NotesTable._ID));
int locationId= cursor.getInt(cursor.getColumnIndex(NotesContract.NotesTable.COLUMN_LOCATION));
String [] retrievedData= {category, summary, description};
if (getActivity().findViewById (R.id.fragment_container)!=null){
//two pane layout:
listView.setItemChecked(position, true);
listView.setBackgroundColor(Color.BLUE);
Bundle args = new Bundle();
args.putStringArray("data",retrievedData);
/*args.putInt("update", 1);*/
args.putLong("id", id);
args.putInt("locationId", locationId);
mCallback.onlistElementClicked(args );/*this is available in the parent activity*/
}
else {
// one pane layout:
Intent intent = new Intent(getActivity(), NotesDetails.class);
intent.putExtra(Intent.EXTRA_TEXT, retrievedData);
/*intent.putExtra("update", 1); */ //to indicate that the query should be update not insert.
intent.putExtra("id", id);
intent.putExtra("locationId", locationId); //whether it is 0 or 1
startActivity(intent);
}
}//end outer cursor if.
}
});
return rootView;
}
I am getting a NullPointerException when trying to find the image by ID. As can be seen in the second code section, I have first temporarily inflate the view that contains the image in order to be able to get the image by id and update it, then I inflate the original layout of the fragment (rootView), and I returned rootView. Is that correct?
Notes: The activity that I sent the intent to has a different layout from row layout, and the fragment inside that activity has its on layout also.
Any help is appreciated.
Thank you
If you want to use the different xml other than linked to the activity, than you need to inflate the other xml in this activity. Use the code below as per your code:
public View getView(int position, View convertView, ViewGroup parent) {
View view;
view = Inflater.inflate(R.layout.another_xml, parent, false);
/* Get the widget with id name which is defined in the another_xml of the row */
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
/* Populate the another_xml with info from the item */
name.setText(myObject.getName());
/* Return the generated view */
return view;
}
Hope this helps you and I do hope that I have understood your question properly.
Related
I am currently working on an Application wich displays data from a SQLiteDatabase in a listview. This listview is using custom layouts. My intent was to have three different layouts, depending on what the user is doing. The first layout only displays one TextView and a Button (called row_nameonly). If the user presses this button, the layout would switch to a more detailed view (called row_viewentry). Finnaly, if the user presses the button again, the first layout is displayed once more (row_nameonly). I have tried to accomplish this, but have not found a working solution. My current version seems to change the View of the row, but the new layout is not visible. I wish to do this without having to add extra data to the database.
This is the code of the Custom CursorAdapter :
public class EntryListCursorAdapter extends CursorAdapter{
public int viewRequestPosition = -100;
public EntryListCursorAdapter(Context context, Cursor c) {
super(context, c, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.row_nameonly, parent, false);
}
#Override
public void bindView(View view, final Context context, final Cursor cursor) {
ViewGroup parent = (ViewGroup) view.getParent();
if(cursor.getPosition() == viewRequestPosition){
view = LayoutInflater.from(context).inflate(R.layout.row_viewentry, parent, false);
}
if(!(cursor.getPosition() == viewRequestPosition)) {
TextView nameView = (TextView) view.findViewById(R.id.txt_name);
ImageButton expandMoreButton = (ImageButton) view.findViewById(R.id.btn_expandmore);
String name = cursor.getString(cursor.getColumnIndexOrThrow("prename")) + " " +
cursor.getString(cursor.getColumnIndexOrThrow("surname"));
nameView.setText(name);
expandMoreButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
viewRequestPosition = cursor.getPosition();
notifyDataSetChanged();
}
});
}
}
TLDR: Is there a way to have the CursorAdapter change the layout of the view in wich the button was clicked, and have the new layout displayed, without adding extra data to the SQLiteDatabase ?
Thank you
(If you need any more information please ask)
In case someone is curious,
I had the Adapter take the Fragment calling it in its constructor. Then i saved the position of the ListItems i wanted to change the layout of in the fragment wich called the adapter. Then i created a new instance of the adapter, but this time the layout would changed based on the positions i saved in the fragment.
I am consuming a webservice and storing the JSON response in an arraylist. I am displaying the arraylist in a List view in android. My concern here is, say I want only my job id and job status to be displayed in the listview and during the onclick event I need all the data such as job id, job name, job status etc to be displayed.
Currently all the details are shown in the listview itself. I need to hide certain values there.
I tried removing the unwanted fields in the Adapter part. But while doing so, I am unable to retrieve them during the onclick event.
Please help.
ListAdapter adapter = new SimpleAdapter(
JobMain.this, jobList,
R.layout.detail_list, new String[] {"number","name","member","desc","status" }, new int[] { R.id.textView2,
R.id.textView4, R.id.textView6,R.id.textView8,R.id.textView10});
setListAdapter(adapter);
ListView lv = getListView();
lv.setBackgroundResource(R.drawable.background);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String reqno = ((TextView) view.findViewById(R.id.textView2))
.getText().toString();
String name = ((TextView) view.findViewById(R.id.textView4))
.getText().toString();
String member = ((TextView) view.findViewById(R.id.textView6))
.getText().toString();
String description = ((TextView) view.findViewById(R.id.textView8))
.getText().toString();
String status = ((TextView) view.findViewById(R.id.textView10))
.getText().toString();
Yes it is possible.
YOu can either hide it in xml by adding this attribute to your view:
android:visibility="gone"
OR,
Inside your adapter, set the visibility of the view in question to gone.
Either way, inside the onItemClick() of the listview, set the visiblity to visible to make it show when the item is clicked
Like this:
HIDE IN XML
<!--You can choose to hide it here by setting visibility
to gone in xml like this-->
<EditText
android:id="#+id/edit"
android:inputType="text"
android:enabled="true"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
IN CODE INSIDE YOUR ADAPTER getView()
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView==null)
{
holder=new Holder();
convertView=LayoutInflater.from(context).inflate(R.layout.item,parent,false);
holder.editText=(EditText)convertView.findViewById(R.id.edit);
convertView.setTag(holder);
}
else {holder=(Holder)convertView.getTag();}
//hide the views like this
holder.editText.setVisibility(View.GONE);
holder.editText.setEnabled(true);
holder.editText.setHint("type");
then to make it visible when clicked,
inside your getView(), add an onCLickListener to the view you are returning like this:
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//make the view visible when the item is clicked
holder.editText.setVisibility(View.VISIBLE);
}
});
return convertView;
}
You give the ListView.setAdapter(adapter) a ArrayList.
.setOnItemClicklistener() has a position value. Use that to get the object you want from the ArrayList to the next action...
object you_want = ArrayList.get(position);
*And you might want to look into creating your own ArrayAdapter.
I want to dynamically change my UI by checking some condition in my onCreate activity . But my app crashes .
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.busdetail);
Intent i=getIntent();
String s=i.getStringExtra("fname");
Log.d("ssssss: ",s);
if(s=="itemName1")
{
for(int k=0;k<itemName1.length;k++)
{
arrayk[k]=itemName1[k];
}
}
CustomList adapter = new CustomList(this, arrayk, imageId);
list = (ListView) findViewById(R.id.list);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//String selectedItem = itemName[+position];
// Toast.makeText(getApplicationContext(),selectedItem,Toast.LENGTH_LONG).show();
Intent intent = new Intent(BusDetail.this, AddComment.class);
startActivity(intent);
}
});
}
Here if (s=="itemName1") then I copy itemName1 into arrayk. Both itemName1 and arrayk are string array . But when I clicked an item, my app crashes. When I avoid if condition block then my app runs well.
Two things.
First, to compare a String, don't use == ! You have to compare the value of the String, not the object itself. Your condition is wrong now... == compares the object references but not the content.
Use the following condition: if(s.equals("itemName1"))
or use equalsIgnoreCase("itemName1") if you want to ignore the case.
Then Remember that during the onCreate, your UI is not ready yet. If you have any change to do in the UI, do it in the onCreateView
//////////////////////////////////////////////////////////
onCreateView is working this way:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View mainview = inflater.inflate(R.layout.yourlayout, container, false);
//mainview is your main view, use it to find your elements, assign them listeners, change text, attributes, etc
return mainview; //you have to return this view
}
It is basically working like onCreate except that this is were you have to manage everything linked to your views and to your UI. It's also there that you have to inflate the view you need, and to return it.
currently I'm searching for a solution to populate a ListView with content from 3 different SQLite tables. When tapped, each ListView item (row) should show the according detailed view (Activity), which is based on one of the three xml layouts.
Any suggestions?
Edit:
Currently I solved this for one type of Object/SQLite table.
Fetching content from SQLite table into an ArrayList and pass it via putExtra to the detail activity, which handles setting texts/content.
The matching of the listView entry and starting the according detail view is solved with the arrayList index with matches to the listView index.
I'm not sure, if this is a proper solution. I guess it isn't...
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent typeOne_details_intent = new Intent(this, TypeOneDetailActivity.class);
typeOne_result = new TypeOneResult();
typeOne_result = typeOneResult_arr.get(position);
typeOne_details_intent.putExtra("result", TypeOneResult);
startActivity(typeOne_details_intent);
}
How can I solve this to add typeTwoDetails and get a better matching between listview and according detailview?
You can use a Custom Adapter that that can determine what Activity to start, set custom row view, etc. One way, you could create a row object Interface, and check the Object type to determine the layout for the row and set things such as the onClick listener and which Activity to launch.
Quick example below:
public class CustomAdapter extends BaseAdapter<ListObjectInterface>{
...
ListObjectInterface data[];
....
public CustomAdapter(Context context, int layoutResourceId, ListObjectInterface[] data) {
...
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
... /* do things. such as check if instance is present, etc. */
ListObjectInterface object = data[position];
if (object instanceOf TypeA) {
row = inflater.inflate(layoutResourceIdA, parent, false);
...
... /* get View objects and set Button listener to launch Activity A */
} else if (object instanceOf TypeB) {
row = inflater.inflate(layoutResourceIdB, parent, false);
...
... /* get View objects and set Button listener to launch Activity B */
} ... /* etc */
... /* more logic */
return row;
}
}
I'm developing an application for android and now I have implemented a ListView that shows a list of courses, connected to a database.
I would like to know how to include, with the name, an hidden id (that come from the db) so that once the user click on the elements the app goes to the relative view of the selected courses.
And how can I maintain the id during the navigation inside the course-view?
At the moment my code just load the name of the courses from the db and set in the list view:
ArrayAdapter<String> result = new ArrayAdapter<String>(CourseActivity.this, android.R.layout.simple_list_item_1);
for (CourseRecord c : get())
result.add(c.getFullname());
lv.setAdapter(result);
obviously I'm able to do also c.getid() but I don't where to put the id.
Thank you very much.
P.S.: Maybe does someone have also a really nice graphics of list view?
change your array adapter like this.
private ArrayAdapter<String> result = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1){
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
v.setTag(getMyIdForPosition(position));
return convertView;
}
};
and have an item click handler to recieve the selected ids
private OnItemClickListener itemClickedHandler = new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id)
{
String myId = (String)v.getTag();
doYourStuff(myId);
}
};
assign the listener to the list
myList= (ListView)findViewById(R.id.history);
myList.setOnItemClickListener(itemClickedHandler);
You can store the id in a hidden TextView. In the list item XML, add 'android:visibility="gone"' to the TextView. Likewise in the click handler you can read the id from the textview.
You can also store id using setTag(Object object) method of a View. Use getTag() method to extract that id from that view.