I've made a decent effort to find a similar question and failed, so please forgive me if this is redundant pollution.
I have a ListView and an ImageButton defined in the xml file "my_layout" corresponding to my Activity as follows:
<ListView
android:id="#+id/listViewItems"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
></ListView>
and
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/btn_delete_dark"
android:id="#+id/buttonDelete"
android:layout_weight="1">
</ImageButton>
I then populate the ListView programmatically in the onCreate() method of my Activity as follows:
public class ViewItemsActivity extends Activity implements OnClickListener,
OnItemClickListener{
ImageButton buttonDelete;
ListView listViewItems;
DatabaseHandler dbHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout);
buttonDeleteQuestion = (ImageButton) findViewById(R.id.buttonDelete);
listViewQuestions = (ListView) findViewById(R.id.listViewItems);
buttonDelete.setOnClickListener(this);
//get data from sql table containing items
dbHandler = new DatabaseHandler(this);
String [] items = dbHandler.getItems(); //get data to populate ListView
CustomAdapter adapter = new CustomAdapter(this,
android.R.layout.simple_list_item_1, items);
listViewItems.setAdapter(adapter);
listViewItems.setOnItemClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonDelete:
listViewItems.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listViewItems.setItemChecked(0, true);
break;
//other cases are irrelevant
}
}
#Override
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
// TODO Auto-generated method stub
//non relevant code
}
}
Everything works as it should except that I want the ListView to change, in appearance and functionality, as a result of clicking buttonDelete, so that it displays checkmarks to the right of each row which can be checked by clicking on them.
It was my understanding that setChoiceMode(ListView.MULTIPLE_CHOICE) and setItemChecked(i,true) would have this effect, but clearly I've missed something as it does not.
I am quite new to android and so it is possible that I've wasted someone's time with trivialities, for which I apologize.
Thank you very much.
The solution was really simple, and is the following:
in the onClick event corresponding to buttonDelete, I simply created a new adapter whose layout id is *simple_list_item_multiple_choice* and assigned it to the ListView with the lines
CustomAdapter adapter = new CustomAdapter(this,
android.R.layout.simple_list_item_multiple_choice, items);
listViewItems.setAdapter(adapter);
which did the trick.
Related
i have placed a textview and a toggle button into a list view by using the following xml file and i have used an arrayadapter to set it on to my layout, my problem is when i scroll down in the list view by unchecking a few toggle buttons (which are all set to be checked by default), they go back to default state and few others change state. As i want to fetch the state of the toggle button in my later stages its very important to stick on to the state that ive assigned to the toggle button. Please help to resolve this problem. Here are my xml file and the java code i use to set it on to the adapter. thank you in prior...
xml file that is named listdecor is included here
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lvlistdecor"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:orientation="horizontal"
android:weightSum="2" >
<TextView
android:id="#+id/tvlistdecor"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:ellipsize="marquee"
android:singleLine="true"
android:text="sample"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:typeface="sans" />
<CheckBox
android:id="#+id/cbusn_checked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="6sp"
android:layout_weight="0.5"
android:checked="true"
android:focusable="false"
android:padding="10dp" />
</LinearLayout>
Sir i made certain changes and also included the custom adapter to the listview and also changed to CheckBox instead of toggle buttons. but now the entire list view is not visible on my emulator. i've included my edited java class and xml file, please suggest me the changes, thank you...
The modified java code is included here
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // Setting the window to full screen Step 1
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); // Setting the window to full screen Step 2
setContentView(R.layout.attendance5);
facid = (TextView) findViewById(R.id.tvfacid);
facname = (TextView) findViewById(R.id.tvfacname);
subjectchosen = (TextView) findViewById(R.id.tvsubject);
// llattendlist = (LinearLayout)findViewById(R.id.llattendlist);
String Uid = getIntent().getStringExtra("Uid");
facid.setText(Uid);
String Name = getIntent().getStringExtra("Name");
facname.setText(Name);
String Sub = getIntent().getStringExtra("Sub");
subjectchosen.setText(Sub);
Attendusn = getIntent().getExtras();
if(Attendusn!=null)
{
AttendStud_usn = (ArrayList<String>)Attendusn.getStringArrayList("AttendStud_usn");
}
String AttendLen = String.valueOf(AttendStud_usn.size());
//int flag = 0 ;
//subjectchosen.setText(String.valueOf(AttendStud_usn));
myListView = (ListView) findViewById(R.id.lvnames);
// myListView.setAdapter(new ArrayAdapter<String>(this, R.layout.listdecoration,R.id.tvlistdecor, AttendStud_usn));
//ArrayAdapter<String> MyAdapter= new ArrayAdapter<String>(this,R.layout.listdecoration, R.id.tvlistdecor,AttendStud_usn);
//myListView.setAdapter(MyAdapter);
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View item, int position,
long id) {
// TODO Auto-generated method stub
Stud_usn usn= MyAdapter.getItem(position);
usn.toggleChecked();
Stud_usnViewHolder vh_usn= (Stud_usnViewHolder) item.getTag();
vh_usn.getCheckBox().setChecked(usn.isChecked());
}
});
MyAdapter = new Stud_Adapter(this,AttendStud_usn);
myListView.setAdapter(MyAdapter);
}
private static class Stud_usn{
private String usn_no="";
private boolean checked=true;
public Stud_usn(String usn_no){
this.usn_no = usn_no;
}
public String getUsn(){
return usn_no;
}
public void setChecked(boolean checked){
this.checked=checked;
}
public Object isChecked() {
// TODO Auto-generated method stub
return checked;
}
public String toString(){
return usn_no;
}
public void toggleChecked() {
// TODO Auto-generated method stub
checked = !checked;
}
}
private static class Stud_usnViewHolder{
private CheckBox checkbox;
private TextView textview;
public Stud_usnViewHolder(TextView textview, CheckBox checkbox){
this.checkbox=checkbox;
this.textview=textview;
}
public CheckBox getCheckBox() {
// TODO Auto-generated method stub
return checkbox;
}
public TextView getTextView(){
return textview;
}
}
private static class Stud_Adapter extends ArrayAdapter<Stud_usn>{
public LayoutInflater inflater;
public Stud_Adapter(Context context, List<String> attendStud_usn) {
super(context,R.layout.listdecoration,R.id.tvlistdecor);
// TODO Auto-generated constructor stub
inflater = LayoutInflater.from(context);
}
public View getView(int position, View convertView, ViewGroup parent){
Stud_usn usn = (Stud_usn) this.getItem(position);
CheckBox checkbox;
TextView textview;
if(convertView == null){
convertView = inflater.inflate(R.layout.listdecoration,null);
textview = (TextView) convertView.findViewById(R.id.tvlistdecor);
checkbox = (CheckBox) convertView.findViewById(R.id.cbusn_checked);
}
return convertView;
}
}
}
The view objects are recycled. You have to store that info sepperately. Not in the view but in the with the data you use in the adapter. When generating the views use this info to set the button state again.
You have to implement a custom adapter. Use the BaseAdapter class.
The Context
I have a HomeActivity that contains a NewsFragment. The NewsFragment contains a ListView to display news items in a list. I have a ViewPager that is added as a header-view to the ListView. This ViewPager appears as a header to the list and contains a DateFragment to display the date. The first time the user opens the HomeActivity, I want "TODAY" to be the date. When the user swipes the DateFragment to the left, I want the date text to show "TOMORROW". Swipe again and it should show the day after tomorrow. Similarly, when the user swipes in the other direction, I want to display "YESTERDAY", the day before yesterday etc. The ViewPager should support swiping infinitely (or a very large number) in both directions.
Here's how they are nested - http://tinypic.com/r/31623qw/8. (I don't have the reputation to post images yet, but this diagram is super useful for understanding this question).
The Problem
For simplicity, I'm displaying the index of the fragment as the date. When I first open the app, I see "Date: 0" being displayed as the date in the DateFragment. When I swipe the fragment to the left (to go to the next day), I can see the next fragment appear with "Date: 1" being displayed, but almost immediately, the fragment disappears. Once the fragment disappears, nothing reappears, and I just see an empty container. I can swipe to bring back the "Date: 0" Fragment, but I can't see any other Fragments. (I'm using the - Infinite View Pager by Antony T. - https://github.com/antonyt/InfiniteViewPager)
The Gory Details
I have a HomeActivity that contains a NewsFragment. The NewsFragment contains a ListView to display news items as a list. Here is the layout.xml for the NewsFragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
I have a ViewPager that is dynamically added as a header to this list. So inside NewsFragment, I first initialize the ListView:
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.home_news_fragment, container, false);
list = (ListView) view.findViewById(android.R.id.list);
emptyView = view.findViewById(android.R.id.empty);
list.setEmptyView(emptyView);
return view;
}
Next, in onActivityCreated(), I initialize and load the header for the ListView, and then load the news feed items:
#Override
public void onActivityCreated(final Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
loadHeader();
loadNewsFeed();
}
In the loadHeader() method, I then dynamically create a LinearLayout container to contain my ViewPager. I create a PagerAdapter for the ViewPager and I wrap it with an InfiniteViewPager to allow infinite swiping in both directions. I then create a ViewPager and I add it to the LinearLayout container. I then add the container as a Header View to the ListView:
private void loadHeader()
{
final LinearLayout headerContainer = new LinearLayout(getActivity());
headerContainer.setId(R.id.header_container_id);
headerContainer.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
headerContainer.setOrientation(LinearLayout.VERTICAL);
// initialize the pager adapter for the view pager
PagerAdapter pagerAdapter = new HeaderPagerAdapter(getActivity().getSupportFragmentManager());
// Create a view pager. I use a custom implementation of a view pager I found from another Stackoverflow answer - WrapContentHeightViewPager - that allows ViewPager's layout.height to wrap content. The original ViewPager does not allow wrapping of content.
WrapContentHeightViewPager mViewPager = new WrapContentHeightViewPager(getActivity());
mViewPager.setId(R.id.view_pager_header);
mViewPager.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
// wrap pager to provide infinite paging with wrap-around
PagerAdapter wrappedAdapter = new InfinitePagerAdapter(pagerAdapter);
mViewPager.setAdapter(wrappedAdapter);
// Add the view pager to the header container
headerContainer.addView(mViewPager);
// add the container as a header view to the list
list.addHeaderView(headerContainer);
}
In the loadNewsFeed() method, I do an async fetch of the news feed items and populate the list by adding the items into the footer view. I won't go into the implementation details for this - outside the scope of this question.
The NewsFragment contains my pager adapter, which contains the getItem method that initializes the Fragment to be displayed by the ViewPager:
private class HeaderPagerAdapter extends FragmentPagerAdapter
{
public HeaderPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
return DateFragment.newInstance(i);
}
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
}
And here is the actual Fragment to be displayed inside the ViewPager:
public class DateFragment extends Fragment
{
private int index;
TextView date;
public static final DateFragment newInstance(int index) {
DateFragment fragment = new DateFragment();
final Bundle args = new Bundle(1);
args.putInt(Constants.Extras.PAGE_INDEX, index);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
index = getArguments() != null ? getArguments().getInt(Constants.Extras.PAGE_INDEX) : 1;
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState)
{
View v = (ViewGroup) inflater.inflate(R.layout.summary_fragment, container, false);
date = (TextView) v.findViewById(R.id.tvDate);
return v;
}
#Override
public void onActivityCreated(final Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
date.setText("Date: " + index);
}
}
For now I am simply using the index to be displayed as the date. I want to replace this with the actual date. Why does the fragment disappear on swipe?
Considerations:
Is there a refresh/redraw event that gets called?
Does it have to do with extending FragmentPagerAdapter vs. FragmentStatePagerAdapter
Override destroyItem() or instantiateItem()?
Set up a onPageScrolled listener on the ViewPager and then handle the page scroll events? I tried thehayro.blogspot.com/2012/12/enable-infinite-paging-with-android.html and that causes my fragments to disappear and then appear after a while.
Is it because I am adding the ViewPager as a header to the list view? The list view scrolls up and down and the view pager left and right. I've added this to my ViewPager implementation to tell the list view to stop intercepting our touch events:
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
// Tell our parent to stop intercepting our events!
boolean ret = super.onInterceptTouchEvent(ev);
if (ret)
{
getParent().requestDisallowInterceptTouchEvent(true);
}
return ret;
}
I'm sorry about the length of this post. I felt this much detail might be necessary. Thoughts?
I have been looking in thousand posts for this, but I do not find how to solve my problem.
I have an ImageView. When the user clicks on this ImageView, a DialogFragment is displayed, and the user can choose between taking a new picture with the camera, or selecting a picture from the gallery. Until here everything works fine.
The problem is, that the picture selected by the user, should replace the current one in the ImageView, but this bit, is the one that is not working, because the onActivityResult() function that executes this code is not being executed, so the image in the ImageView always remains the same. I would appreciate any help, because I do not see or understand, why this code is not being executed.
I am getting a warning in the LogCat right after the user selects the image:
05-07 12:17:11.542: I/ActivityManager(59): Displayed activity com.android.gallery/com.android.camera.ImageGallery: 935 ms (total 935 ms)
05-07 12:17:12.812: W/FragmentActivity(3614): Activity result no fragment exists for index: 0x10001
05-07 12:17:12.862: W/InputManagerService(59): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy#45fd9c38 (uid=10016 pid=317)
Activity.java:
private ImageView imageLoader = null;
imageLoader = (ImageView) findViewById(R.id.f_imageLoader);
imageLoader.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
ImageLoaderDialog imageLoaderDialog = new ImageLoaderDialog(imageLoader);
imageLoaderDialog.show(getSupportFragmentManager(), "imageLoaderDialog");
}
Activity.xml:
<ImageView
android:id="#+id/f_imageLoader"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="0.20"
android:contentDescription="#string/imgDesc"
android:src="#drawable/my_image" />
ImageLoaderDialog.java:
//Dialog for choosing between new camera image or gallery image.
public class ImageLoaderDialog extends android.support.v4.app.DialogFragment {
private ImageView targetImageView = null;
final int TAKE_PICTURE = 0;
final int PICK_PHOTO = 1;
public ImageLoaderDialog (View view) {
targetImageView = (ImageView) view;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Selecciona");
final String[] imageSources = getResources().getStringArray(R.array.imageSources);
builder.setItems(imageSources, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
switch(item) {
case TAKE_PICTURE:
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, TAKE_PICTURE);
break;
case PICK_PHOTO:
Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto, PICK_PHOTO);
break;
}
}
});
return builder.create();
}
//Set image to user's selected image.
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == android.app.Activity.RESULT_OK) {
Uri selectedImage = intent.getData();
Log.i("IMAGEN", ""+selectedImage);
targetImageView.setImageURI(selectedImage);
}
}
}
Any help would be very appreciated.
The hosting activity overrode the onActivityResult but did not make a call to super.onActivityResult for unhandled result codes. Apparently even though the fragment is the one making the startActivityForResult call, the activity gets the first shot at handling the result. This makes sense when you consider the modularity of fragments. Once I implemented super.onActivityResult for all unhandled results, the fragment got a shot at handling the result.Try This:
getActivity().onActivityResult(requestCode, resultCode, intent);
I'm trying to show a DialogFragment asking the user his name, and I need to get back this string to my main activity.
I've created an custom dialog fragment following the android guide: http://developer.android.com/guide/topics/ui/dialogs.html#CustomLayout
In my code, in response to the user click on positive button, I am able to call a function in my main activity:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
builder.setView(inflater.inflate(R.layout.textdialog, null)).setPositiveButton("OK", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int id) {
((mainActivity)getActivity()).doPositiveClick();
}
}).setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
((mainActivity)getActivity()).doNegativeClick();
}
});
return builder.create();
}
where R.layout.textdialog is:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/textdraw"
android:inputType="textEmailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"
android:hint="introduce text" />
</LinearLayout>
My question is, how could I get the text written by the user in my dialog fragment and send it back to my main activity?
thanks!
Well, I solved myself (but not sure if it's the better way)
I've done some changes in my onCreateDialog.
Save the view in a variable:
View v= inflater.inflate(R.layout.textdialog, null);
Save the edittext in a variable:
final EditText ed=(EditText)v.findViewById(R.id.textdraw);
Send back the value in edittext variable when the user clicks the positive button:
getActivity()).doPositiveClick(ed.getText().toString());
Full code is here:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
View v= inflater.inflate(R.layout.textdialog, null);
// reference to the edittext
final EditText ed= (EditText)v.findViewById(R.id.textdraw);
builder.setView(v).setPositiveButton("OK", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int id) {
((mainActivity)getActivity()).doPositiveClick(ed.getText().toString());
}
}).setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
((mainActivity)getActivity()).doNegativeClick();
}
});
return builder.create();
}
and the code in main activity:
public void doPositiveClick(String ed){
Toast.makeText(this, "Hi, "+ed, Toast.LENGTH_SHORT).show();
}
Hello everyone I've been stick with this problem, and I can't see my mistake. I had used before basicly for having different drawable bind to a specific level, nevertheless I am trying to use it within a BroadcastReceiver wich monitor battery changes, the problem is that I don't get any UI update when I called the setImageLevel change?
The Broadcast Receiver goes like this
public class BatteryReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG, "Fired Changed");
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = (level * 100) / scale;
imageBattery = (ImageView) findViewById(R.id.imageBatery);
imageBattery.setImageLevel(percent);
Log.d(LOG, "On UI running I am");
// imageBattery.getDrawable().mutate();
// imageBattery.invalidate();
// Log.d(LOG,"DRawable: "+((LevelListDrawable)imageBattery.getDrawable()).getCurrent());
}
}
The Log gets displayed but it does not change my ImageView if you can point me out in the right direction, or you have any insight on this issue?
Little bit of more info
Here is my Registration and unregistration both on the same activity as the BroadcastReceiver
#Override
public void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.BATTERY_CHANGED");
registerReceiver(receiver, filter);
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
How do I instatiate the ImageView Drawable:
<ImageView
android:id="#+id/imageBatery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/battery_status" />
And also battery_status.xml is a drawable (I removed some of the drawable item because you get the idea I have from 0-100)
<item
android:drawable="#drawable/stat_sys_battery_100"
android:maxLevel="100"/>
<item
android:drawable="#drawable/stat_sys_battery_90"
android:maxLevel="90"/>
<item
android:drawable="#drawable/stat_sys_battery_80"
android:maxLevel="80"/>
Do You have your BroadcastReceiver inlined in Your Activity? If so, use 'MyActivity.this.runOnUiThread()` method to change Your views.
your problem is in images
LevelListDrawable doesn't append new image when level changed, it just shows the image for level you've set
try differen images and you'll see what I mean
try this in your onCreate:
imageBattery = (ImageView) findViewById(R.id.imageBatery);
for (int i = 0; i < 10; i++) {
imageBattery.setImageLevel(i * 10);
}
is smth changed ?