我正在尝试在android中创建一个应用程序,其中我将拥有两组数据。我必须在每个数据集的顶部显示标题。
所以我选择用tableLayout显示数据的输出。我需要在每行中填充5个单元格。
例如:
*Header1*
dataSet1.1 dataSet1.2 dataSet1.3 dataSet1.4 dataSet1.5
dataSet1.1 dataSet1.2 dataSet1.3 dataSet1.4 dataSet1.5
dataSet1.1 dataSet1.2 dataSet1.3 dataSet1.4 dataSet1.5
dataSet1.1 dataSet1.2 dataSet1.3 dataSet1.4 dataSet1.5
*Header2*
dataSet2.1 dataSet2.2 dataSet2.3 dataSet2.4 dataSet2.5
dataSet2.1 dataSet2.2 dataSet2.3 dataSet2.4 dataSet2.5
dataSet2.1 dataSet2.2 dataSet2.3 dataSet2.4 dataSet2.5
dataSet2.1 dataSet2.2 dataSet2.3 dataSet2.4 dataSet2.5
我能够填充数据,但是当设备较小时,只有该行的一半可见,其余行被裁剪。我的意思是,从该行开始,仅显示dataSet1.1,dataSet1.2和dataSet1.3的一半,其余部分被裁剪。每行都发生相同的情况。
下面是我的代码。
片段(Java):
public class VideoFragment extends Fragment implements VideoFragmentView
{
private static final int NUMBER_OF_COLUMNS = 5;
private static final long REFRESH_TIMEOUT_MINUTES = 15;
private static final int NUMBER_OF_COLUMNS = 4;
private static final long REFRESH_TIMEOUT_MINUTES = 15;
private GuideMediaItemAdapter guideMediaItemAdapter;
TableLayout mainTable;
private LocalBroadcastManager localBroadcastManager;
public static VideoFragment newInstance()
{
VideoFragment fragment = new VideoFragment();
return fragment;
}
@Override
public void toLoadingState()
{
// No - Op
}
@Override
public void toLoadedState()
{
// No - Op
}
@Override
public void onCreate(Bundle savedInstanceState)
{
DaggerVideoFragmentComponent.builder()
.applicationComponent(((PhoenixApp) getContext().getApplicationContext()).getComponent())
.videoFragmentModule(new VideoFragmentModule(this))
.build()
.inject(this);
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_nav_video_content_table_view, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
getPresenter().start();
/**
* TODO : Add below given two for loops into one.
*/
mainTable = (TableLayout) view.findViewById(R.id.displayLinear);
TableRow guideHeaderRow = new TableRow(getContext());
View guideHeaderView = LayoutInflater.from(getContext()).inflate(R.layout.guide_header_nav_item, null);
guideHeaderRow.addView(guideHeaderView);
mainTable.addView(guideHeaderRow);
TableRow falseRow1 = new TableRow(getContext());
falseRow1.setMinimumHeight(10);
mainTable.addView(falseRow1);
for (int i = 0; i < guideMediaItemAdapter.getCount(); i++)
{
TableRow row = new TableRow(getContext());
for (int j = 0; j < 4 && i < guideMediaItemAdapter.getCount(); j++)
{
int tmp = i++;
View viewToAdd = guideMediaItemAdapter.getView(tmp, null, null);
Entity entity = (Entity) guideMediaItemAdapter.getItem(tmp);
row.addView(viewToAdd);
if (j == 3)
{
i--;
mainTable.addView(row);
}
}
}
mainTable.setVisibility(View.VISIBLE);
}
@Override
public void setGridAdapter(BaseNavContentFragment.MediaItemAdapter adapter)
{
// No - Op. Do not set any general adapter.
}
@Override
public void setGuideGridAdapter(GuideMediaItemAdapter adapter)
{
guideMediaItemAdapter = adapter;
}
@Override
public void onDestroy()
{
getPresenter().stop();
super.onDestroy();
}
public static class GuideMediaItemAdapter extends BaseAdapter
{
private static String LOGTAG = "GuideMediaItemAdapter";
private final List<Entity> items;
private final LayoutInflater layoutInflater;
private final int firstLastRowPadding;
private final int stationMargins;
private final Context mContext;
public GuideMediaItemAdapter(Context context, List<Entity> items)
{
this.mContext = context;
this.layoutInflater = LayoutInflater.from(context);
this.items = items;
firstLastRowPadding = ViewUtil.convertDpToPx(context, 16);
stationMargins = context.getResources().getDimensionPixelSize(R.dimen.radio_logo_tile_inset);
}
@Override
public int getCount()
{
return items.size();
}
@Override
public Object getItem(int position)
{
return items.get(position);
}
@Override
public long getItemId(int position)
{
return items.get(position).id.hashCode();
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View itemView;
// fetch the item from the list/grid.
Entity entity = items.get(position);
if (convertView == null)
{
itemView = layoutInflater.inflate(R.layout.nav_item, null);
}
else
{
itemView = convertView;
}
ImageView titleIcon = itemView.findViewById(R.id.titleIcon);
if (entity instanceof Station)
{
titleIcon.setImageResource(R.drawable.ic_radio_small);
titleIcon.setVisibility(View.VISIBLE);
}
else if (entity instanceof Ad && !((Ad) entity).isArtist)
{
titleIcon.setImageResource(R.drawable.ic_ad_mcdonalds);
titleIcon.setVisibility(View.VISIBLE);
}
else
{
titleIcon.setVisibility(View.GONE);
}
TextView titleTextView = itemView.findViewById(R.id.title);
titleTextView.setText(entity.title);
titleTextView.setVisibility(View.VISIBLE);
TextView subtitleView = itemView.findViewById(R.id.subtitle);
if (!TextUtils.isEmpty(entity.subtitle))
{
subtitleView.setText(entity.subtitle);
subtitleView.setVisibility(View.VISIBLE);
}
else
{
subtitleView.setVisibility(View.GONE);
}
TextView badgeStandardAd = itemView.findViewById(R.id.badgeStandardAd);
badgeStandardAd.setVisibility(View.GONE);
TextView badge = itemView.findViewById(R.id.badge);
badge.setVisibility(View.GONE);
ImageView imageOverlayView = itemView.findViewById(R.id.imageOverlay);
imageOverlayView.setVisibility(View.GONE);
if (entity instanceof Ad && ((Ad) entity).isArtist)
{
badge.setText(R.string.sponsored_artist);
badge.setVisibility(View.VISIBLE);
}
if (entity instanceof Station && ((Station) entity).isProgram)
{
Station station = (Station) entity;
badge.setText(station.startTime + " - " + station.endTime);
badge.setVisibility(View.VISIBLE);
}
ImageView artView = itemView.findViewById(R.id.image);
artView.setImageResource(R.drawable.album_art_placeholder);
artView.setVisibility(View.VISIBLE);
if (entity instanceof Station && !((Station) entity).isProgram)
{
ViewUtil.setMargins(imageOverlayView, stationMargins);
ViewUtil.setMargins(artView, stationMargins);
}
else
{
ViewUtil.setMargins(imageOverlayView, 0);
ViewUtil.setMargins(artView, 0);
}
int lastRowNumberOfItems = getCount() % NUMBER_OF_COLUMNS;
if (lastRowNumberOfItems == 0)
{
lastRowNumberOfItems = 5;
}
if (position < NUMBER_OF_COLUMNS)
{
//top first row
itemView.setPadding(0, firstLastRowPadding, 0, 0);
}
else if (position >= getCount() - lastRowNumberOfItems)
{
//bottom last row
itemView.setPadding(0, 0, 0, firstLastRowPadding);
}
else
{
itemView.setPadding(0, 0, 0, 0);
}
return itemView;
}
}
}
片段(布局):
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical"
android:layout_gravity="center"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingBottom="15dp"
android:paddingTop="15dp">
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:id="@+id/displayLinear"
android:scrollbars="vertical"
android:padding="10dp"
android:gravity="center">
</TableLayout>
</ScrollView>
nav_item(用于创建该行各项的布局):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#fff"
android:clipChildren="false"
android:clipToPadding="false">
<android.support.v7.widget.CardView
android:id="@+id/imageContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/nav_item_background"
android:clipChildren="false"
android:clipToPadding="false"
app:cardCornerRadius="10dp"
app:cardElevation="4dp"
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />
<ImageView
android:id="@+id/imageOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:background="#b4ffffff"
android:scaleType="centerInside" />
<TextView
android:id="@+id/badge"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:background="#ccffffff"
android:textColor="@android:color/black"
android:textSize="10sp"
android:text="@string/sponsored_artist"
android:visibility="gone"
tools:visibility="visible"
android:paddingTop="6dp"
android:paddingBottom="3dp"
android:paddingStart="6dp"
android:paddingEnd="6dp"
android:fontFamily="@font/lato_regular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/badgeStandardAd"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:background="#046c4f"
android:textColor="@android:color/white"
android:textAllCaps="true"
android:textSize="10sp"
tools:text="Exit 29"
android:visibility="gone"
tools:visibility="gone"
android:paddingTop="6dp"
android:paddingBottom="3dp"
android:paddingStart="6dp"
android:paddingEnd="6dp"
android:fontFamily="@font/lato_regular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
<LinearLayout
android:id="@+id/titleContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/imageContainer"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/titleIcon"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginRight="6dp" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/lato_bold"
android:lines="1"
android:textColor="#000"
android:textSize="16sp" />
</LinearLayout>
<TextView
android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/titleContainer"
android:layout_marginLeft="10dp"
android:fontFamily="@font/lato_regular"
android:ellipsize="end"
android:lines="1"
android:textColor="#63666a"
android:textSize="14sp" />
</RelativeLayout>
关于stackOverflow的问题很多,但大多数问题是针对静态表的,我已经尝试了其中的大多数问题,使表可滚动,但行从视图中溢出是这里的问题,我无法解决。
你们可以帮我吗?
答案 0 :(得分:1)
我发现我做错了。我没有为该行中的每个单元格设置layoutParams。为每个单元格添加适当的layoutParam即可解决问题。
以下是我所做的代码更改:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
getPresenter().start();
/**
* TODO : Add below given two for loops into one.
*/
mainTable = (TableLayout) view.findViewById(R.id.displayLinear);
TableRow guideHeaderRow = new TableRow(getContext());
View guideHeaderView = LayoutInflater.from(getContext()).inflate(R.layout.guide_header_nav_item, null);
guideHeaderRow.addView(guideHeaderView);
mainTable.addView(guideHeaderRow);
TableRow falseRow1 = new TableRow(getContext());
falseRow1.setMinimumHeight(10);
mainTable.addView(falseRow1);
for (int i = 0; i < guideMediaItemAdapter.getCount(); i++)
{
TableRow row = new TableRow(getContext());
for (int j = 0; j < 4 && i < guideMediaItemAdapter.getCount(); j++)
{
int tmp = i++;
View viewToAdd = guideMediaItemAdapter.getView(tmp, null, null);
// Adding these two lines will solve the problem
TableRow.LayoutParams params = new TableRow.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f);
viewToAdd.setLayoutParams(params);
// -------------
Entity entity = (Entity) guideMediaItemAdapter.getItem(tmp);
row.addView(viewToAdd);
if (j == 3)
{
i--;
mainTable.addView(row);
}
}
}
mainTable.setVisibility(View.VISIBLE);
}
答案 1 :(得分:0)
您解决问题的方法不是一个好方法,这也许就是为什么您会遇到视图裁剪问题的原因。您正在根据数据集中的项目数量动态创建视图。您可以使用Android的GridView或RecyclerView来处理带有间距装饰的列表,以及使用GridLayoutManager的GridLayoutManager,它使用spanCount的主要构造函数参数,该参数是网格所需的列数,然后您将需要创建自己的Recycler扩展。附加到RecyclerView的适配器以及RecyclerView.ViewHolder类的许多所需扩展,它们分别表示数据的视图类型。第一个是一个很好的解决方案,但根据Android准则here,推荐第二个。它将为您提供对所处理列表的精确控制。对于列表中不同类型的数据视图,您可以重写扩展适配器类的getItemViewType方法以区分列表的页眉,页脚和内容,如果您不希望列表可滚动,也可以在RecyclerView上禁用滚动希望可以解决您的问题。