Android Studio & Kotlin: Changing programmatically added images of a list view - android-studio

Hey fellow programmers,
I was just programming in a listView and implementing actions for tapping a list element until I got to a point where I wanted to keep things recursively.
Taken this ClickListener, I would like to have the image next to the list element changed when tapped.
list.add(Model("firstelement","description 1", R.drawable.button_activated))
list.add(Model("secondelement","description 2",R.drawable.button_activated))
listview.adapter = MyAdapter(this, R.layout.row, list)
var elementArray: IntArray = intArrayOf(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
listview.setOnItemClickListener{ parent: AdapterView<*>, view: View, position:Int, id: Long ->
val currentimage = ? //here I'd like to retrieve the imageview of the tapped list item
val img: ImageView = findViewById(R.id.currentimage)
if (elementArray.get(position)==0){
img.setImageResource(R.drawable.button_activated)
elementArray.set(position,1)
}
else if (elementArray.get(position)==1){
img.setImageResource(R.drawable.button_dectivated)
elementArray.set(position,0)
The images are added to the list together with the text view.
How can I retrieve them to change them? Tried listview.getItemIdAtPosition but that leads to errors.
I bet there is a way - I just don't see it. Thanks in advance for any hint!
In addition, here is my layout row.xml where the list gets loaded into:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
>
<ImageView
android:layout_width="75dp"
android:layout_height="75dp"
android:id="#+id/image0"
android:src="#mipmap/ic_launcher"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/textView1"
android:text="first element"
android:textStyle="bold"
android:textSize="20sp"
android:layout_margin="5dp"
android:textColor="#000"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView2"
android:text="second element"
android:textSize="18sp"
android:layout_margin="5dp"
android:textColor="#a9a9a9"
/>
</LinearLayout>
</LinearLayout>

Just resolved it on my own with the help of this solution: Android: Dynamically change Image in Listview
Had to access the lower imageView of the current view: ImageView = view.findViewById(R.id.image)

Related

I want to implement Image Gallery using View Pager with static footer. In footer I have 3 button download, share and Favorite

Now the problem is that when I like the first image remaining images also show the red heart icon and vice versa...can any body help me how to change the icon in footer by swiping the image?
By clicking on favorite button ivFavImage the following listener is called
if (databaseHandler.checkData(DatabaseModel(stringPaths[vpSingleItem.currentItem]))) {
ivFavImage.setImageResource(R.drawable.ic_favorite_red)
} else if (!databaseHandler.checkData(DatabaseModel(stringPaths[vpSingleItem.currentItem]))){
ivFavImage.setImageResource(R.drawable.ic_favorite_white)
}
ivFavImage.setOnClickListener {
if (!databaseHandler.checkData(DatabaseModel(stringPaths[vpSingleItem.currentItem]))) {
databaseHandler.insertData(DatabaseModel(stringPaths[vpSingleItem.currentItem]))
ivFavImage.setImageResource(R.drawable.ic_favorite_red)
Toast.makeText(context, "Image added to Favorite Designs", Toast.LENGTH_SHORT)
.show()
} else if (databaseHandler.checkData(DatabaseModel(stringPaths[vpSingleItem.currentItem]))) {
databaseHandler.deleteImage(DatabaseModel(stringPaths[vpSingleItem.currentItem]))
ivFavImage.setImageResource(R.drawable.ic_favorite_white)
Toast.makeText(context, "Image removed from Favorite Designs", Toast.LENGTH_SHORT)
.show()
}
}
I have declared the layout as this
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:orientation="vertical"
android:weightSum="1">
<androidx.viewpager.widget.ViewPager
android:id="#+id/vpSingleItem"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.9" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.1"
android:background="#color/colorPrimaryDark">
<ImageView
android:id="#+id/ivDownloadImage"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:src="#drawable/download_white" />
<ImageView
android:id="#+id/ivFavImage"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_favorite_white" />
<ImageView
android:id="#+id/ivShareImage"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="10dp"
android:src="#drawable/share_icon" />
</RelativeLayout>
</LinearLayout>
change icon's state in viewPager.setOnPageChangeListener()
get icon state from your model and change footer based on current position of viewPager

How to make LinearLayout Clickable with multiple textView in It?

I have a XML file like below. I want to make the first layout clickable, I used android:clickable="true", but click is not working on whole part, only some part is responding to click. How to make the whole Layout clickable?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:gravity="center_vertical">
<LinearLayout
android:id="#+id/clicableLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/task_finish"
android:background="#color/colorPrimary"
android:clickable="true"
android:orientation="vertical">
<TextView
android:id="#+id/task_title"
android:layout_width="195dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:clickable="true"
android:text="Hello"
android:textColor="#color/HeadingColor"
android:textSize="22sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/DateText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:text="Date"
android:textColor="#color/DateColor"
android:textStyle="italic|bold" />
<TextView
android:id="#+id/TimeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:text="Time"
android:textColor="#color/TimeColor"
android:textStyle="italic|bold" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Ask more clearly about the problem. If you want to click on the LinearLayout then set an onClickListener on the id of the LinearLayout.
you need to implement on click listener , one way of achieving this is by the following code :
yourView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//what after the view got clicked
}
});

Why my Android setOnItemClickListener doesn't work?

I have problem in setting setOnItemClickListener. The following is my code. I've tested that setAdapter worked and the list and items were shown on the UI. When it came to setting setOnItemClickListener, it didn't work.
cool_simpleAdapter = new SimpleAdapter(this, items,
R.layout.mylistitem, new String[] { "title", "link" }, new int[] {
R.id.textView_title, R.id.textView_link });
cool_listView.setAdapter(cool_simpleAdapter);
Log.d("tag_1", "before setOnItemClickListener");
cool_listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.d("tag_setonItemClick", "in onItemClick");
Uri uri = Uri.parse("http://www.google.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
Log.d("tag_2", "after setOnItemClickListener");
I put the log to trace what happened:
Log.d("tag_1","before setOnItemClickListener");
and
Log.d("tag_2","after setOnItemClickListener");
were displayed but
Log.d("tag_setonItemClick","in onItemClick");
were not displayed. And I cannot click on the item, neither open the URL. I don't know how should I fix the problem.
Edit: add mylistitem.xml layout
<?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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/textView_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
in this condition your Button is focused so listiten setOnItemClickListener not working..so make them focusable false..
add this line in xml of Button on
android:focusable="false"
I had this problem before, that was because each item of listview had a Button.
to solve this just need to set android:focusable of the button to false.
I hope this will help you

ListView row height and another interesting issue of selective focus (when the parent is scrolled)

First of all, excuse me if it sounds duplicate. I have visited so many threads but couldn't find a suitable answer of my problem. I have tried ScrollingMovementMethod, android:scrollbar, wrap_content in the parent and many other things suggested in those threads but nothing worked for me. Feel free to edit the title as I couldn't find a better one.
Problem Description
I have a list view and each row of the listview has three controls 1. Image View (to Show the contact image) 2. TextView (to show the Contact name) 3. TextView (to show the status message of the contact (if available)).
What I have tried:-
1. XML layout ,
<?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" >
<ImageView
android:id="#+id/icon"
android:layout_width="22dp"
android:layout_height="50dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="15dp"
android:contentDescription="#string/strBuddyImage" >
</ImageView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="56dp" >
<TextView
android:id="#+id/uNameTxt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/customMsg"
android:minHeight="?android:attr/listPreferredItemHeight"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="#dimen/fontSizeListRowHeader" />
<TextView
android:id="#+id/customMsg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:maxLines="4"
android:textSize="#dimen/fontSizeListRowText"
android:textStyle="italic" />
</RelativeLayout>
</LinearLayout>
Adapter Which extends ArrayAdapter (which only overrides the getView method)
static class ViewHolder {
public ImageView imageView;
public TextView uNameTxtView;
public TextView custMsgTxtView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// Log.d("BuddyListAdapter", "Inside getView() " + position);
if ( rowView == null ) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.buddy_listview_row_layout, parent, false);
viewHolder = new ViewHolder();
viewHolder.uNameTxtView = (TextView) rowView.findViewById(R.id.uNameTxt);
viewHolder.imageView = (ImageView) rowView.findViewById(R.id.icon);
viewHolder.custMsgTxtView = (TextView) rowView.findViewById(R.id.customMsg);
rowView.setTag(viewHolder);
}
viewHolder = (ViewHolder) rowView.getTag();
synchronized (buddyList) {
buddy = buddyList.get(position);
}
viewHolder.uNameTxtView.setText(buddy.getDisplayName());
viewHolder.custMsgTxtView.setText(buddy.getCustomMessage());
// Change the icon for users who are offline
if ( buddy.getState() == 0 ) {
viewHolder.imageView.setImageResource(R.drawable.offline);
} else {
viewHolder.imageView.setImageResource(R.drawable.online);
}
// rowView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
return rowView;
}
What I get
Desired
I want to show all the rows of list view of same size and if someone has a bigger Status message (Which needs multiple lines) I would like to show the name of the person and first few lines (say 4) of the status message. No matter how big the status message is name should be always visible to the user.. How can I do that ?
Please point if any other mistake you find in the code.
One thing i noticed is you use a lot of hardcoded dimensions,is that really necesary? using wrap_content would be better practice on most layouts,that way you let android handle it.
As far as your question is concerned you can do two things:
1)Your two EditTexts are inside a relative layout,and if customMsg is 4 lines long,it will get scrolled ,and you'll loose your uNameTxt so you should limit customMsg more,to something like two lines,or less. OR if you are ok with loosing some parts of the code you could adapt your layout this way
<TextView
android:id="#+id/uNameTxt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout_alignParentTop="true"
android:minHeight="?android:attr/listPreferredItemHeight"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="#dimen/fontSizeListRowHeader" />
<TextView
android:id="#+id/customMsg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/uNameTxt"
android:maxLines="4"
android:textSize="#dimen/fontSizeListRowText"
android:textStyle="italic" />
it should scroll down no more and you should see Name and a part of customMsg
2)Edit your layout to something more efficient like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="56dp">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginRight="15dp"
android:contentDescription="sasd" >
</ImageView>
<TextView
android:id="#+id/uNameTxt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:singleLine="true"
android:layout_toRightOf="#+id/icon"
android:textSize="#dimen/fontSizeListRowHeader"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="#+id/customMsg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/uNameTxt"
android:maxLines="2"
android:layout_toRightOf="#+id/icon"
android:textSize="#dimen/fontSizeListRowText"
android:textStyle="italic" />
</RelativeLayout>
I agree with sokie on the use of wrap_content. I tend to use LinearLayout a lot since it provides a consistent layout on various display sizes. One way of implementation is as follows. By replacing your inner RelativeLayout to LinearLayout, your text view containing the name will always be displayed and the message text view will display the maximum possibles lines (or can be limited by specifying the maxLines) with the available remaining/space. If you would like to display the whole status message, then you can achieve this by changing the parent LinearLayout height parameter to wrap_content.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="56dp"
android:minHeight="?android:attr/listPreferredItemHeight">
<ImageView
android:id="#+id/icon"
android:layout_width="22dp"
android:layout_height="50dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="15dp" >
</ImageView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/uNameTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="#+id/customMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="4"
android:textStyle="italic"
/>
</LinearLayout>
</LinearLayout>

Set default text style when using AlertDialog.Builder.setCustomTitle()

This might be easy but I can't find the answer anywhere.
I'm using setCustomTitle for my alert dialog in order to use my own view for the dialog title:
View customTitle = getLayoutInflater().inflate(R.layout.dialog_title, null);
new AlertDialog.Builder(AddBusActivity.this).setCustomTitle(customTitle).(some more stuff).show();
And dialog_title.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:text="My Title"
android:id="#+id/title"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="right|center_vertical">
</TextView>
</LinearLayout>
My problem is making the title TextView use the default dialog title style.
In my device the alert dialog background is dark, so text has to be bright, but in other devices it might be different.
I tried adding android:textAppearance="#android:style/TextAppearance.DialogWindowTitle" to the TextView, but it caused the text to be black which isn't the right style.
How can I solve this?
I had similar problem with styles and colors, but resolved it by using custom Dialog instead of AlertDialog.
1) my code with
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle(mName);
...
mDialog = builder.create();
mDialog.show();
was changed to
dialog = new Dialog(mContext);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_custom_title);
// initializing Views
dialog.show();
2) in layout.dialog_custom_title set needed styles (background and color)
<LinearLayout xmlns: android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/dialogs_background"
android:orientation="vertical" >
...
<TextView
...
android:textColor="#color/TxtLightBlue"
android:textSize="#dimen/text_size_default"
/>
...
Hope it will help someone.
I used the code below whiuch set the colors and the spacing quite well
<TextView android:text="My Title"
android:id="#+id/title"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:textSize="24sp"
android:textColor="#color/green"
android:textStyle="bold"
android:paddingBottom="#dimen/activity_vertical_margin"
android:gravity="center_horizontal|center_vertical">
</TextView>

Resources