That’s because you’re echoing the Parent term name outside of the loop.
$custom_terms = get_terms('material_category');
foreach($custom_terms as $custom_term) {
$args = array('post_type' => 'materials',
'tax_query' => array(
array(
'taxonomy' => 'material_category',
'field' => 'slug',
'terms' => array('general-english')
),
),
);
$loop = new WP_Query($args);
if ($loop->have_posts()) {
while ($loop->have_posts()) : $loop->the_post();
echo '<h2>' . $custom_term->name . '</h2>';
echo '<a href="' . get_permalink() . '">' . get_the_title() . '</a>';
endwhile;
}
wp_reset_query();
}