I am programming a custom shipping method (store pickup).
I added an additional Dropdown Menu with this tutorial: https://zanetabaran.com/how-to-in-magento-2-how-to-add-additional-dropdown-with-options-based-on-selected-shipping-methods-in-the-checkout/
The Values from the dropdown are static at the moment, coming from a js-File from my module->
Pastebin
updateDropdownValues: function(method) {
var valuesCollection = [];
if(method['carrier_code'] == 'customshipping'){
valuesCollection = [
{
label: 'Store1',
value: 'Store1'
},
{
label: 'Store2',
value: 'Store2'
},
{
label: 'Store3',
value: 'Store3'
}
];
} else {
valuesCollection = [];
}
self.updateDropdown(valuesCollection);
},
The dropdown is defined in checkout_index_index.xml -> Pastebin
<item name="shippingAdditional" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="displayArea" xsi:type="string">shippingAdditional</item>
<item name="children" xsi:type="array">
<item name="shipping-option-wrapper" xsi:type="array">
<!-- Component Magento_Checkout/js/view/additional-shipping-option is used as a wrapper for content -->
<item name="component" xsi:type="string">XXX_CustomShipping/js/view/additional-shipping-option</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="sortOrder" xsi:type="string">0</item>
<item name="children" xsi:type="array">
<item name="shipping-option" xsi:type="array">
<!-- uiComponent is used as a wrapper for select (its template will render all children as a list) -->
<item name="component" xsi:type="string">uiComponent</item>
<!-- the following display area is used in template -->
<item name="displayArea" xsi:type="string">additionalShippingOptionField</item>
<item name="children" xsi:type="array">
<item name="markt" xsi:type="array">
<item name="component" xsi:type="string">XXX_CustomShipping/js/view/shipping-option-select</item>
<item name="config" xsi:type="array">
<!--customScope is used to group elements within a single form (e.g. they can be validated separately)-->
<item name="customScope" xsi:type="string">shippingOptionSelect</item>
<item name="template" xsi:type="string">ui/form/field</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
</item>
<item name="dataScope" xsi:type="string">shippingOptionSelect.select_data</item>
<item name="label" xsi:type="string" translate="true">Please choose a market</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
<item name="validate-no-empty" xsi:type="boolean">true</item>
</item>
<item name="sortOrder" xsi:type="number">0</item>
</item>
</item>
</item>
</item>
</item>
</item>
How can I get values from a class into the dropdown? Right now, I only can access values from the quote class. I need to access my own (just fyi: to show different availabilities for the different stores)
If more infos needed, feel free to ask for them. Thank you in advance.
Ok, i figured it out.
I added an index-controller <Your_Vendor>/<YourModule>/Controller/Options/index.php, and declared it in <Your_Vendor>/<YourModule>/etc/frontent/routes.xml and can get the values with ajax:
updateDropdownValues: function(method) {
var valuesCollection = [];
if(method['carrier_code'] == 'customshipping'){
$.ajax({
url:"/<your_declared_route>/Optionen/index",
contentType: "application/json",
async:false,
success:function (data) {
valuesCollection = [];
var wert=[];
$.each(data, function (index, thevalue) {
wert=[];
wert["label"]=index;
wert["value"]=thevalue;
valuesCollection.push(wert);
});
},
error: function (xhr, ajaxOptions, thrownError) {
console.log("There has been an error retrieving the values from the database.");
}
});
}
else {
valuesCollection = [];
}
self.updateDropdown(valuesCollection);
},
My routes.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="yourid" frontName="<your_declared_route>">
<module name="<your_Vendor/Your_Modulname>" />
</route>
</router>
</config>
I will extend this answer with custom collection( Custom Table ) for any type of dropdown generation. Ex - Show Stores Drop Down.
let customurl = urlBuilder.build('pickupstores/storeoptions/index');
// urlBuilder.build('frontname/storeoptions/index');
updateDropdownValues: function(method) {
var valuesCollection = [];
if(method['carrier_code'] === 'storepickup'){ //You can add your own logic here,
//I added this to show stores dropdown only customer choose custom shipping method **storepickup**
$.ajax({
url:customurl,
type: 'POST',
contentType: "application/json",
async:false,
success:function (data) {
valuesCollection = [];
$.each(JSON.parse(data) , function(index, val) {
valuesCollection.push({
label: val,
value: val
});
});
},
error: function (xhr, ajaxOptions, thrownError) {
console.log("There has been an error retrieving the values from the database.");
}
});
}
self.updateDropdown(valuesCollection);
},
My Controller file
<?php
namespace Ayakil\CustomShippingMethod\Controller\StoreOptions;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Exception\NotFoundException;
use Ayakil\PickupStores\Model\PickupStores; // My custom module to get stores
use Magento\Framework\Controller\Result\JsonFactory;
class Index implements HttpPostActionInterface
{
protected $pickupStores;
protected $resultJsonFactory;
public function __construct(
PickupStores $pickupStores,
JsonFactory $resultJsonFactory,
array $data = array()
) {
$this->pickupStores = $pickupStores;
$this->resultJsonFactory = $resultJsonFactory;
}
public function execute(){
$resultJson = $this->resultJsonFactory->create();
$collection = $this->pickupStores->getCollection();
$storesCollection = $collection->getData();
$stores = [];
foreach($storesCollection as $store){
$stores[] = $store['store_name'];
}
return $resultJson->setData(json_encode($stores));
}
}
I hope this answer will save some ones time in future.
Related
I have created several custom product attributes and I need them to display on the Product Details tab if data has been entered in the Magento Admin. There are three in total and on a lot of occasions all three will have data but there will be around 20% of products where one or two of the have data.
I have created the attributes easily enough but I am struggling to get them to display on the frontend. I have pasted the code for the layout file and the phtml file for the attributes.
The result I am getting is a blank product screen with no info at all. Definitely an error somewhere but after hours of looking I am missing it.
Below is the custom catalog_product_view.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<page layout="2columns-right" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<move element="product.info.stock.sku" destination="product.info.price" after="product.price.final"/>
<move element="page.main.title" destination="product.info.main" before="-"/>
<referenceBlock name="product.info.overview" remove="true"/>
<referenceBlock name="product.info.details">
<block class="Magento\Catalog\Block\Product\View\Description" name="product.info.description." template="Magento_Catalog::product/view/product_attributes.phtml" group="detailed_info">
<arguments>
<argument name="at_call" xsi:type="string">getDescription</argument>
<argument name="at_code" xsi:type="string">description</argument>
<argument name="css_class" xsi:type="string">description</argument>
<argument name="at_label" xsi:type="string">none</argument>
<argument name="title" translate="true" xsi:type="string">Product Details</argument>
</arguments>
</block>
<block class="Magento\Catalog\Block\Product\View" name="deliveryinfo.tab" as="deliveryinfo" template="product/view/delivery_info.phtml" group="detailed_info" >
<arguments>
<argument translate="true" name="title" xsi:type="string">Delivery</argument>
</arguments>
</block>
</referenceBlock>
<referenceContainer name="sidebar.main">
<block class="Magento\Cms\Block\Block" name="sidebar_delivery" after="-">
<arguments>
<argument name="block_id" xsi:type="string">sidebar_delivery</argument>
</arguments>
</block>
<block class="Magento\Cms\Block\Block" name="sidebar_instructions" after="-">
<arguments>
<argument name="block_id" xsi:type="string">sidebar_instructions</argument>
</arguments>
</block>
<block class="Magento\Cms\Block\Block" name="sidebar_brochures" after="-">
<arguments>
<argument name="block_id" xsi:type="string">sidebar_brochures</argument>
</arguments>
</block>
<block class="Magento\Cms\Block\Block" name="sidebar_blog" after="-">
<arguments>
<argument name="block_id" xsi:type="string">sidebar_blog</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
Below is product_attributes.phtml called in the Layout file
<?php
$_helper = $this->helper('Magento\Catalog\Helper\Output');
$_product = $block->getProduct();
$_code = $block->getAtCode();
$_className = $block->getCssClass();
$_attributeLabel = $block->getAtLabel();
$_attributeType = $block->getAtType();
$_attributeAddAttribute = $block->getAddAttribute();
if ($_attributeLabel && $_attributeLabel == 'default') {
$_attributeLabel = $_product->getResource()->getAttribute($_code)->getFrontendLabel();
}
$_attributeValue =$_product->getResource()->getAttribute($_code)->getFrontend()->getValue($_product);
?>
<?php if ($_attributeValue): ?>
<div>
<?php if ($_attributeLabel != 'none'): ?><strong class="type"><?php echo $_attributeLabel?></strong><?php endif; ?>
<div class="value" <?php echo $_attributeAddAttribute;?>><?php echo $_attributeValue; ?></div>
</div>
<?php endif; ?>
<?php
$dimensions = $_product->getResource()->getAttribute('dimensions')->getFrontend()->getValue($_product);
$features_benefits = $_product->getResource()->getAttribute('features_benefits')->getFrontend()->getValue($_product);
$flooring_specification = $_product->getResource()->getAttribute('flooring_specification')->getFrontend()->getValue($_product);
if (!empty($dimensions) || !empty($features_benefits) || !empty($flooring_specification) {
?>
<?php
if (!empty($dimensions)) {
?>
<h2>Dimensions</h2>
<?php echo $dimensions; ?>
<?php
}
if (!empty($features_benefits)) {
?>
<h2>Features & Benefits</h2>
<?php echo $features_benefits; ?>
<?php
}
if (!empty($flooring_specification)) {
?>
<h2>Specification</h2>
<?php echo $flooring_specification; ?>
<?php
}
?>
<?php
}
?>
It is probably something laughably simple I have done wrong but I can't for the life of me find it.
The site is on Community Edition 2.2.5 and the server is running PHP 7.1
Any suggestions appreciated.
Kev
Solved the issue in the end. I missed out a closing bracket.
This line:
if (!empty($dimensions) || !empty($features_benefits) || !empty($flooring_specification) {
Should have been:
if (!empty($dimensions) || !empty($features_benefits) || !empty($flooring_specification)) {
I knew it would have been something simple. Works perfectly now.
I have created a step in checkout between shipping step and payment step according to magento documentation Add a new checkout step
But when I display the checkout, step 1 and step 2 are vissible in the same view, how can I make it to show step 1 first and step 2 later?
I'm using Magento 2.1.
Here is my code:
layout/checkout_index_index.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<!-- The new step you add -->
<item name="contacts" xsi:type="array">
<item name="component" xsi:type="string">CloudMobile_Contacts/js/view/contacts</item>
<!--To display step content before shipping step "sortOrder" value should be < 1-->
<!--To display step content between shipping step and payment step 1 < "sortOrder" < 2 -->
<!--To display step content after payment step "sortOrder" > 2 -->
<!--<item name="sortOrder" xsi:type="string">2</item>-->
<item name="children" xsi:type="array">
<!--add here child component declaration for your step-->
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
web/js/view/contacts.js
define(
[
'ko',
'uiComponent',
'underscore',
'Magento_Checkout/js/model/step-navigator',
'Magento_Customer/js/model/customer',
'jquery'
],
function (
ko,
Component,
_,
stepNavigator,
customer,
$
) {
'use strict';
/**
*
* mystep - is the name of the component's .html template,
* <Vendor>_<Module> - is the name of the your module directory.
*
*/
return Component.extend({
defaults: {
template: 'CloudMobile_Contacts/contacts'
},
//add here your logic to display step,
isVisible: ko.observable(true),
/**
*
* #returns {*}
*/
initialize: function () {
this._super();
// register your step
stepNavigator.registerStep(
//step code will be used as step content id in the component template
'contacts',
//step alias
null,
//step title value
'Contacto',
//observable property with logic when display step or hide step
this.isVisible,
_.bind(this.navigate, this),
/**
* sort order value
* 'sort order value' < 10: step displays before shipping step;
* 10 < 'sort order value' < 20 : step displays between shipping and payment step
* 'sort order value' > 20 : step displays after payment step
*/
15
);
this.getContacts(this);
return this;
},
/**
* The navigate() method is responsible for navigation between checkout step
* during checkout. You can add custom logic, for example some conditions
* for switching to your custom step
*/
navigate: function () {
},
/**
* #returns void
*/
navigateToNextStep: function () {
this.saveContact();
stepNavigator.next();
},
/**
* Obtiene la lista de contactos relacionados a la cuenta
* #param {Object} scope
* #returns void
*/
getContacts: function(scope){
var url = 'some_url';
$.ajax({
url: url,
type: 'GET',
crossDomain: true,
jsonpCallback: 'jsonCallback',
dataType: 'jsonp',
data: {
accountnum: customer.customerData.custom_attributes.sfdc_id.value
}
})
.success(function(response){
scope.contacts = response;
});
},
/**
* Guarda en la orden al contacto que realizó el pedido
* #param void
* #returns void
*/
saveContact: function(){
console.log($('select#contact').val());
}
});
}
);
web/js/template/html.js
<li id="contacts" data-bind="fadeVisible: isVisible">
<div class="step-title" data-bind="i18n: 'Contacto'" data-role="title"></div>
<div id="checkout-step-title"
class="step-content"
data-role="content">
<form data-bind="submit: navigateToNextStep" novalidate="novalidate">
<select name="contacto" id="contact">
<!-- ko foreach: contacts -->
<option data-bind="value: Id,
text: Name"></option>
<!-- /ko -->
</select>
<div class="actions-toolbar">
<div class="primary">
<button data-role="opc-continue" type="submit" class="button action continue primary">
<span><!-- ko i18n: 'Next'--><!-- /ko --></span>
</button>
</div>
</div>
</form>
</div>
</li>
Screenshot:
Checkout
Solved!
To avoid mixed steps views, I just changed this:
isVisible: ko.observable(true)
For this:
isVisible: ko.observable(false)
I am working on Magento2 dynamic massaction, but I am not getting dynamic tree massaction part in order grid. So I reference one link and I got following solution, still I am not getting desired output. Let me know where I am going wrong.
<massaction name="listing_massaction">
<action name="magento_hello">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="type" xsi:type="string">magento_hello</item>
<item name="label" xsi:type="string" translate="true">change to group buyer</item>
</item>
</argument>
<argument name="actions" xsi:type="array">
<argument name="class" xsi:type="string">Magento\Hello\Ui\Component\MassAction\Group\Options</argument>
<argument name="data" xsi:type="array">
<item name="urlPath" xsi:type="string">customertobuyer/masschangetobuyer</item>
<item name="paramName" xsi:type="string">group</item>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">change to group buyer</item>
<item name="message" xsi:type="string" translate="true">Are you sure to change selected customerto buyer and to assign sto new group buyer?</item>
</item>
</argument>
</argument>
</action>
</massaction>
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Hello\Ui\Component\MassAction\Group;
use Magento\Framework\UrlInterface;
use Zend\Stdlib\JsonSerializable;
use Magento\Customer\Model\ResourceModel\Group\CollectionFactory;
/**
* Class Options
*/
class Options implements JsonSerializable
{
/**
* #var array
*/
protected $options;
/**
* #var CollectionFactory
*/
protected $collectionFactory;
/**
* Additional options params
*
* #var array
*/
protected $data;
/**
* #var UrlInterface
*/
protected $urlBuilder;
/**
* Base URL for subactions
*
* #var string
*/
protected $urlPath;
/**
* Param name for subactions
*
* #var string
*/
protected $paramName;
/**
* Additional params for subactions
*
* #var array
*/
protected $additionalData = [];
/**
* Constructor
*
* #param CollectionFactory $collectionFactory
* #param UrlInterface $urlBuilder
* #param array $data
*/
public function __construct(
CollectionFactory $collectionFactory,
UrlInterface $urlBuilder,
array $data = []
) {
$this->collectionFactory = $collectionFactory;
$this->data = $data;
$this->urlBuilder = $urlBuilder;
}
/**
* Get action options
*
* #return array
*/
public function jsonSerialize()
{
if ($this->options === null) {
$options = $this->collectionFactory->create()->setRealGroupsFilter()->toOptionArray();
$this->prepareData();
foreach ($options as $optionCode) {
$this->options[$optionCode['value']] = [
'type' => 'customer_group_' . $optionCode['value'],
'label' => $optionCode['label'],
];
// if ($this->urlPath && $this->paramName) {
// $this->options[$optionCode['value']]['url'] = $this->urlBuilder->getUrl(
// $this->urlPath,
// [$this->paramName => $optionCode['value']]
// );
// }
$this->options[$optionCode['value']] = array_merge_recursive(
$this->options[$optionCode['value']],
$this->additionalData
);
}
$this->options = array_values($this->options);
}
return $this->options;
}
/**
* Prepare addition data for subactions
*
* #return void
*/
protected function prepareData()
{
foreach ($this->data as $key => $value) {
switch ($key) {
case 'urlPath':
$this->urlPath = $value;
break;
case 'paramName':
$this->paramName = $value;
break;
default:
$this->additionalData[$key] = $value;
break;
}
}
}
}
Please try with this xml and update your controller action as needed
<massaction name="listing_massaction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="selectProvider"xsi:type="string">vendorName_moduleName_list.vendorName_moduleName_columns.ids</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
<item name="indexField" xsi:type="string">id</item>
</item>
</argument>
<action name="magento_hello">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="type" xsi:type="string">magento_hello</item>
<item name="label" xsi:type="string" translate="true">change to group buyer</item>
<!-- set you action path-->
<item name="url" xsi:type="url" path="path_to_controller"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">change to group buyer</item>
<item name="message" xsi:type="string" translate="true">Are you sure to change selected customerto buyer and to assign sto new group buyer?</item>
</item>
</item>
</argument>
</action>
</massaction>
I think there is a issue with the function jsonSerialize() in UI component class.
Please try below.
public function jsonSerialize()
{
$i=0;
if ($this->options === null) {
// get the massaction data from the database table
$collection = $this->collectionFactory->create()->setRealGroupsFilter()->toOptionArray();
if(!count($collection)){
return $this->options;
}
//make a array of massaction
foreach ($collection as $key => $badge) {
$options[$i]['value']=$badge->getEntityId();
$options[$i]['label']=$badge->getTitle();
$i++;
}
$this->prepareData();
foreach ($options as $optionCode) {
$this->options[$optionCode['value']] = [
'type' => 'customer_group_' . $optionCode['value'],
'label' => $optionCode['label'],
];
if ($this->urlPath && $this->paramName) {
$this->options[$optionCode['value']]['url'] = $this->urlBuilder->getUrl(
$this->urlPath,
[$this->paramName => $optionCode['value']]
);
}
$this->options[$optionCode['value']] = array_merge_recursive(
$this->options[$optionCode['value']],
$this->additionalData
);
}
// return the massaction data
$this->options = array_values($this->options);
}
return $this->options;
}
Show category with images in homepage Magento2
http://ibnab.com/en/blog/magento-2/magento-2-frontend-how-to-call-category-collection-on-home-page
This article working fine but I need to show category image.How to fetch category images also
I am using $category->getImageUrl();
but its not working
I was able to get this to show on the homepage by combining the tutorial and R T's answer. Because i didn't have a _objectManager (and the page was kicking an error when i tried R T's code) working on that page, I included the category model in the block file (Collection.php)
protected $_categoryHelper;
protected $categoryFlatConfig;
protected $topMenu;
protected $categoryView;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Helper\Category $categoryHelper,
\Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState,
\Magento\Theme\Block\Html\Topmenu $topMenu,
\Magento\Catalog\Model\Category $categoryView
) {
$this->_categoryHelper = $categoryHelper;
$this->categoryFlatConfig = $categoryFlatState;
$this->topMenu = $topMenu;
$this->categoryView = $categoryView;
parent::__construct($context);
}
I then added a method to call in the phtml at the bottom of the block file.
public function getCategoryView() {
return $this->categoryView;
}
In the phtml (storecategories.phtml) I changed up the code to work like this.
<?php
$categories = $this->getStoreCategories(true,false,true);
$categoryHelper = $this->getCategoryHelper();
?>
<ul>
<?php
foreach($categories as $category):
if (!$category->getIsActive()) {
continue;
}
?>
<li><a href="<?php echo $categoryHelper->getCategoryUrl($category) ?>">
<?php
$catId = $category->getId();
$categoryAgain = $this->getCategoryView()->load($catId);
$_outputhelper = $this->helper('Magento\Catalog\Helper\Output');
$_imgHtml = '';
if ($_imgUrl = $categoryAgain->getImageUrl()) {
$_imgHtml = '<img src="' . $_imgUrl . '" />';
$_imgHtml = $_outputhelper->categoryAttribute($categoryAgain, $_imgHtml, 'image');
/* #escapeNotVerified */
echo $_imgHtml;
}
?>
<?php echo $category->getName() ?></a></li>
<?php endforeach; ?>
</ul>
And then i added the new call into the di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Ibnab\CategoriesSide\Block\CategorisCollection">
<arguments>
<argument name="deleteorderAction" xsi:type="array">
<item name="context" xsi:type="string">\Magento\Framework\View\Element\Template\Context</item>
<item name="helper" xsi:type="string">\Magento\Catalog\Helper\Category</item>
<item name="flatstate" xsi:type="string">\Magento\Catalog\Model\Indexer\Category\Flat\State</item>
<item name="menu" xsi:type="string">\Magento\Theme\Block\Html\Topmenu</item>
<item name="categoryview" xsi:type="string">\Magento\Catalog\Model\Category</item>
</argument>
</arguments>
</type>
I've managed to do this as below in template:
$category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($item->getId());
$_outputhelper = $this->helper('Magento\Catalog\Helper\Output');
$_imgHtml = '';
if ($_imgUrl = $category->getImageUrl()) {
$_imgHtml = '<img src="' . $_imgUrl . '" />';
$_imgHtml = $_outputhelper->categoryAttribute($category, $_imgHtml, 'image');
/* #escapeNotVerified */
echo $_imgHtml;
}
hope it helps
In my android application i have list view and detail view for each list item. For tablets i have shown list view of items and selected item's detail view as follows.
So my problem is how can i highlight the selected item after user clicks on list item.
I am using a BaseAdapter to load list view.How can i do this any idea??
EDIT:
Yes as chintan khetiya mentioned i have used following xml file as the background of list item but it will not delighted the selected item. What have i missed?
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="#color/abs__background_holo_light" />
<item android:state_pressed="true"
android:drawable="#color/action_bar_blue" />
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="#color/action_bar_blue" />
</selector>
Your Query :
my problem is how can i highlight the selected item after user clicks on list item.
I think you are asking about selector. Mean if the list row in focus state then it should be look different form all other row. Same thing when you press or Touch the Row.
For that you have to make Selector.xml File in Drawable folder and just put that selector file in your list row
That file should have different tag like Focus-Click-Press and change the Drawable as per state.
Update :
Just Replace Your icon and save in Drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Pressed -->
<item android:drawable="#drawable/p_paly_press" android:state_pressed="true"/>
<!-- selected -->
<item android:drawable="#drawable/p_play" android:state_selected="true"/>
<!-- focused -->
<item android:drawable="#drawable/p_paly_press" android:state_focused="true"/>
<!-- default -->
<item android:drawable="#drawable/p_play"/>
</selector>
The code similar to the following code below can be used to highlight the selected item for sure if other ways do not do that you need:
class Adapter extends ArrayAdapter<String> {
private int selectedPos = -1;
Drawable selectedBackground;
public MainSelectAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
selectedBackground =
context.getResources().getDrawable(R.color.selecteditembackground);
}
public void setSelectedPosition(int pos){
selectedPos = pos;
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if (selectedPos == position) {
v.setBackgroundDrawable(selectedBackground);
} else {
v.setBackgroundDrawable(null);
}
return v;
}
}
And the in the main activity
Adapter adapter = new Adapter(this, android.R.layout.simple_list_item_1,
myItemsToShow);
list = (ListView) findViewById(R.id.flows);
list.setItemsCanFocus(true);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View view,
int pos, long id) {
adapter.setSelectedPosition(pos);
}
});
With this approach, you take own control on the selected item highlighting, you have a listener to capture selection events and you set yourself the required Drawable.
You can define in your styles.xml
<style name="Theme.Base" parent="...">
<item name="activatableItemBackground">#drawable/activatable_item_background</item>
</style>
<style name="ListItemContainerBase">
<item name="android:background">?activatableItemBackground</item>
</style>
In res/drawable define activatable_item_background.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/item_pressed" android:state_pressed="true" />
<item android:drawable="#drawable/item_focused" android:state_focused="true" />
<item android:drawable="#drawable/item_focused" android:state_selected="true" />
<item android:drawable="#drawable/item_activated" android:state_activated="true" />
<item android:drawable="#drawable/item_checked" android:state_checked="true" />
<item android:drawable="#android:color/transparent" />
</selector>
item_pressed, item_focused..... are images in res/drawable-xxx
Define for each items in your view a layout like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/ListItemContainerBase">