Reputation: 62549
How does Google implement the secondary action on some of its views. The entire parent view of the secondary action responds to touch. Here is an example of what im referring to as a secondary action with the secondary action view highlighted:
Here we can either make a phone call as the primary action by clicking on the left side or clicking after the seperator does a secondary action. I would like to know if there is something on a API level to implement this and if not can you recommend 3rd party. I suppose I could design it myself as well.
Upvotes: 0
Views: 756
Reputation: 7089
Please refer to the Android Source Code:
Here's the Code (ContactDetailFragment.java):
Firstly, they define a custom class called DetailViewCache
which is like this:
...
/**
* Cache of the children views of a contact detail entry represented by a
* {@link DetailViewEntry}
*/
private static class DetailViewCache {
public final TextView type;
public final TextView data;
public final ImageView presenceIcon;
public final ImageView secondaryActionButton;
public final View actionsViewContainer;
public final View primaryActionView;
public final View secondaryActionViewContainer;
public final View secondaryActionDivider;
public final View primaryIndicator;
public DetailViewCache(View view,
OnClickListener primaryActionClickListener,
OnClickListener secondaryActionClickListener) {
type = (TextView) view.findViewById(R.id.type);
data = (TextView) view.findViewById(R.id.data);
primaryIndicator = view.findViewById(R.id.primary_indicator);
presenceIcon = (ImageView) view.findViewById(R.id.presence_icon);
actionsViewContainer = view.findViewById(R.id.actions_view_container);
actionsViewContainer.setOnClickListener(primaryActionClickListener);
primaryActionView = view.findViewById(R.id.primary_action_view);
secondaryActionViewContainer = view.findViewById(
R.id.secondary_action_view_container);
secondaryActionViewContainer.setOnClickListener(
secondaryActionClickListener);
secondaryActionButton = (ImageView) view.findViewById(
R.id.secondary_action_button);
secondaryActionDivider = view.findViewById(R.id.vertical_divider);
}
}
...
Then, to inflate the ListView's item:
...
private View getDetailEntryView(int position, View convertView, ViewGroup parent) {
final DetailViewEntry entry = (DetailViewEntry) getItem(position);
final View v;
final DetailViewCache viewCache;
// Check to see if we can reuse convertView
if (convertView != null) {
v = convertView;
viewCache = (DetailViewCache) v.getTag();
} else {
// Create a new view if needed
v = mInflater.inflate(R.layout.contact_detail_list_item, parent, false);
// Cache the children
viewCache = new DetailViewCache(v,
mPrimaryActionClickListener, mSecondaryActionClickListener);
v.setTag(viewCache);
}
bindDetailView(position, v, entry);
return v;
}
...
Then you can find where they defined the onClickListener:
...
private final OnClickListener mSecondaryActionClickListener = new OnClickListener() {
@Override
public void onClick(View view) {
if (mListener == null) return;
if (view == null) return;
final ViewEntry entry = (ViewEntry) view.getTag();
if (entry == null || !(entry instanceof DetailViewEntry)) return;
final DetailViewEntry detailViewEntry = (DetailViewEntry) entry;
final Intent intent = detailViewEntry.secondaryIntent;
if (intent == null) return;
mListener.onItemClicked(intent);
}
};
...
The XML layout (contact_detail_list_item
) Android is using, is shown as below (contact_detail_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright 2009, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<!-- Note: padding might be controlled programatically -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dip">
<com.android.contacts.detail.ActionsViewContainer
android:id="@+id/actions_view_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:nextFocusRight="@+id/secondary_action_view_container"
android:minHeight="@dimen/detail_min_line_item_height">
<!-- Note: padding might be controlled programatically -->
<LinearLayout
android:id="@+id/primary_action_view"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingStart="8dip" >
<TextView
android:id="@+id/data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/presence_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="1dip"
android:layout_marginRight="4dip"
android:layout_marginEnd="4dip"
android:layout_gravity="center_vertical"
android:gravity="center"
android:scaleType="centerInside" />
<TextView
android:id="@+id/type"
style="@style/ContactDetailItemType"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View
android:id="@+id/primary_indicator"
android:layout_width="16dip"
android:layout_height="16dip"
android:visibility="gone"
android:layout_gravity="center_vertical"
android:background="@drawable/ic_list_default_mime_holo_dark" />
</LinearLayout>
</LinearLayout>
<View
android:id="@+id/vertical_divider"
android:layout_width="1dip"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/detail_vertical_divider_vertical_margin"
android:layout_marginBottom="@dimen/detail_vertical_divider_vertical_margin"
android:background="?android:attr/dividerVertical" />
<!-- Note: padding might be controlled programatically -->
Starting from this part is what you're looking for:
<FrameLayout
android:id="@+id/secondary_action_view_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="@dimen/detail_item_icon_margin"
android:paddingEnd="@dimen/detail_item_icon_margin"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:nextFocusLeft="@id/actions_view_container">
<ImageView
android:id="@+id/secondary_action_button"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_gravity="center_vertical"
android:duplicateParentState="false" />
</FrameLayout>
</com.android.contacts.detail.ActionsViewContainer>
</FrameLayout>
Upvotes: 2
Reputation: 67239
There is no built-in API, View, or other feature that will automagically generate this layout.
However, creating this yourself is relatively simple, as there really isn't anything special about this layout.
In your example, the layout for that row might look something like this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp" />
<Button
android:id="@+id/callButton"
android:layout_width="500dp"
android:layout_height="match_parent"
style="@style/transparentButtonStyle" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@drawable/dotted_line" />
<ImageButton
android:id="@+id/smsButton"
android:layout_width="48dp"
android:layout_height="match_parent"
android:src="@drawable/sms_button"
style="@style/transparentButtonStyle" />
</LinearLayout>
You would of course need to provide the transparentButtonStyle, dotted_line drawable, and smsButton drawable. You probably also want to tweak the width of the primary button (perhaps a RelativeLayout would work better).
Upvotes: 1